Browse Source

Added experiment `AreSameImagesReference`, enhanced route meta system

rigwild 1 year ago
parent
commit
ab5e9f5570

experimentConfig.default/Experiments/AreSameImages.js → experimentConfig.default/Experiments/AreSameImagesRandom.js


+ 9 - 0
experimentConfig.default/Experiments/AreSameImagesReference.js

@@ -0,0 +1,9 @@
+import { buildConfig } from '@/functions'
+
+// This will apply to all the scenes
+export const defaultConfig = {}
+
+// This will overwrite the config for the given scene
+export const scenesConfig = {}
+
+export default buildConfig(defaultConfig, scenesConfig)

+ 25 - 8
src/mixins/ExperimentBaseAreSameImages/index.vue

@@ -5,7 +5,6 @@
 </template>
 
 <script>
-import './style.css'
 import ExperimentBase from '@/mixins/ExperimentBase'
 
 import { mapGetters } from 'vuex'
@@ -33,10 +32,9 @@ export default {
       if (ele) ele.scrollIntoView({ behavior: 'smooth' })
     },
 
+    // Get images links for a test
     async getTest(leftQuality, rightQuality) {
-      const left = this.qualities[leftQuality]
-      const right = this.qualities[rightQuality]
-      const res = await Promise.all([this.getImage(left), this.getImage(right)])
+      const res = await Promise.all([this.getImage(leftQuality), this.getImage(rightQuality)])
       const [leftImage, rightImage] = res.map(x => {
         x.link = `${this.getHostURI}${x.link}`
         return x
@@ -44,12 +42,31 @@ export default {
       return { leftImage, rightImage }
     },
 
+    // Get a test with random qualities
     getRandomTest() {
-      return this.getTest(rand(0, this.qualities.length - 1), rand(0, this.qualities.length - 1))
+      return this.getTest(
+        this.qualities[rand(0, this.qualities.length - 1)],
+        this.qualities[rand(0, this.qualities.length - 1)]
+      )
     },
 
-    // An action was triggered, load extracts and save progression
-    async areTheSameActionRandom(areTheSame) {
+    // Get a test with random qualities
+    getReferenceTest() {
+      // Randomly choose which is the reference image (0 = left, 1 = right)
+      const isReferenceLeft = rand(0, 1) === 0
+      // Randomly choose a quality for the other image
+      const randomQuality = this.qualities[rand(0, this.qualities.length - 1)]
+
+      const res = [this.qualities[this.qualities.length - 1], randomQuality]
+      return this.getTest(...(isReferenceLeft ? res : res.reverse()))
+    },
+
+    /** An action was triggered, load a new test and save progression
+     * @param {Boolean} areTheSame Are the images the same
+     * @param {Function} getTestFn Function to be called to get the next tests
+     * @returns {void}
+     */
+    async areTheSameAction(areTheSame, getTestFn) {
       this.loadingMessage = 'Loading new test...'
       this.loadingErrorMessage = null
       try {
@@ -64,7 +81,7 @@ export default {
         }
         this.sendMessage({ msgId: experimentMsgId.DATA, msg: obj })
 
-        const { leftImage, rightImage } = await this.getRandomTest()
+        const { leftImage, rightImage } = await getTestFn()
         this.leftImage = leftImage
         this.rightImage = rightImage
 

+ 0 - 0
src/mixins/ExperimentBaseAreSameImages/style.css


+ 20 - 7
src/router/experiments.js

@@ -2,15 +2,28 @@ export default [
   {
     path: '/experiments/ExperimentWithReference/:sceneName',
     name: 'ExperimentWithReference',
-    fullName: 'With reference image',
     component: () => import('@/views/Experiments/WithReference'),
-    props: true
+    props: true,
+    meta: {
+      fullName: 'Match extracts qualities to reference image'
+    }
   },
   {
-    path: '/experiments/ExperimentAreSameImages/:sceneName',
-    name: 'ExperimentAreSameImages',
-    fullName: 'Are images the same',
-    component: () => import('@/views/Experiments/AreSameImages'),
-    props: true
+    path: '/experiments/ExperimentAreSameImagesRandom/:sceneName',
+    name: 'ExperimentAreSameImagesRandom',
+    component: () => import('@/views/Experiments/AreSameImagesRandom'),
+    props: true,
+    meta: {
+      fullName: 'Are images the same ? (Both are random qualities images)'
+    }
+  },
+  {
+    path: '/experiments/ExperimentAreSameImagesReference/:sceneName',
+    name: 'ExperimentAreSameImagesReference',
+    component: () => import('@/views/Experiments/AreSameImagesReference'),
+    props: true,
+    meta: {
+      fullName: 'Are images the same ? (One is reference image, the other is random quality)'
+    }
   }
 ]

+ 1 - 1
src/views/Experiments/AreSameImages/config.js

@@ -2,7 +2,7 @@ import deepmerge from 'deepmerge'
 import { buildConfig } from '@/functions'
 
 const getMixinConfig = () => import('@/mixins/ExperimentBaseAreSameImages/config')
-const getGlobalConfig = () => import('@/../experimentConfig/Experiments/AreSameImages')
+const getGlobalConfig = () => import('@/../experimentConfig/Experiments/AreSameImagesRandom')
 
 // This will apply to all the scenes
 export const defaultConfig = async () => {

+ 15 - 8
src/views/Experiments/AreSameImages/index.vue

@@ -10,7 +10,8 @@
             </v-btn>
           </v-layout>
 
-          <h1>Experiment Are the images the same - {{ sceneName }}</h1>
+          <h2>Experiment "{{ $route.meta.fullName }}"</h2>
+          <h3>{{ sceneName }}</h3>
         </v-flex>
         <!-- Loading screen -->
         <loader v-if="loadingMessage" :message="loadingMessage" />
@@ -49,11 +50,17 @@
           <!-- Experiment validation button -->
           <v-layout justify-center align-content-center>
             <div id="choice">
-              <h2>Test {{ testCount }} / {{ maxTestCount }}</h2>
-              <v-layout justify-center align-content-center>
-                <v-btn @click="areTheSameActionRandom(false)" color="error" large>Images are NOT the same</v-btn>
-                <v-btn @click="areTheSameActionRandom(true)" color="success" large>Images are the same</v-btn>
-              </v-layout>
+              <v-container grid-list-md text-xs-center fluid>
+                <h2>Test {{ testCount }} / {{ maxTestCount }}</h2>
+                <v-layout row wrap>
+                  <v-flex sm6 xs12>
+                    <v-btn @click="areTheSameAction(false, getRandomTest)" color="error" large>Images are NOT the same</v-btn>
+                  </v-flex>
+                  <v-flex sm6 xs12>
+                    <v-btn @click="areTheSameAction(true, getRandomTest)" color="success" large>Images are the same</v-btn>
+                  </v-flex>
+                </v-layout>
+              </v-container>
             </div>
           </v-layout>
           <!--/ Experiment validation button -->
@@ -70,7 +77,7 @@ import Loader from '@/components/Loader.vue'
 import experimentConfig from './config'
 
 export default {
-  name: 'ExperimentAreTheSame',
+  name: 'ExperimentAreSameImagesRandom',
   components: {
     Loader
   },
@@ -78,7 +85,7 @@ export default {
 
   data() {
     return {
-      experimentName: 'ExperimentAreSameImages'
+      experimentName: 'ExperimentAreSameImagesRandom'
     }
   },
 

+ 37 - 0
src/views/Experiments/AreSameImagesReference/config.js

@@ -0,0 +1,37 @@
+import deepmerge from 'deepmerge'
+import { buildConfig } from '@/functions'
+
+const getMixinConfig = () => import('@/mixins/ExperimentBaseAreSameImages/config')
+const getGlobalConfig = () => import('@/../experimentConfig/Experiments/AreSameImagesReference')
+
+// This will apply to all the scenes
+export const defaultConfig = async () => {
+  // Import parent mixin config
+  const mixinConfig = await getMixinConfig().then(({ defaultConfig: fn }) => fn())
+
+  // Import global config
+  const globalConfig = (await getGlobalConfig()).defaultConfig
+
+  return deepmerge.all([
+    mixinConfig,
+    {},
+    globalConfig
+  ])
+}
+
+// This will overwrite the config for the given scene
+export const scenesConfig = async () => {
+  // Import parent mixin config
+  const mixinConfig = await getMixinConfig().then(({ scenesConfig: fn }) => fn())
+
+  // Import global config
+  const globalConfig = (await getGlobalConfig()).scenesConfig
+
+  return deepmerge.all([
+    mixinConfig,
+    {},
+    globalConfig
+  ])
+}
+
+export default async () => buildConfig(await defaultConfig(), await scenesConfig())

+ 114 - 0
src/views/Experiments/AreSameImagesReference/index.vue

@@ -0,0 +1,114 @@
+<template>
+  <div>
+    <v-container grid-list-md text-xs-center fluid>
+      <v-layout row wrap>
+        <v-flex xs12>
+          <v-layout justify-start>
+            <v-btn flat exact :to="`/experiments/${experimentName}`">
+              <v-icon left>arrow_back</v-icon>
+              Back to scene selection
+            </v-btn>
+          </v-layout>
+
+          <h2>Experiment "{{ $route.meta.fullName }}"</h2>
+          <h3>{{ sceneName }}</h3>
+        </v-flex>
+        <!-- Loading screen -->
+        <loader v-if="loadingMessage" :message="loadingMessage" />
+        <!--/ Loading screen -->
+
+        <!-- Experiment -->
+        <template v-else-if="!loadingErrorMessage">
+          <v-flex xs12 sm6>
+            <v-card dark color="primary">
+              <v-card-text class="px-0">Image 1</v-card-text>
+
+              <v-img v-if="leftImage && leftImage.link" :src="leftImage.link">
+                <template v-slot:placeholder>
+                  <v-layout fill-height align-center justify-center ma-0>
+                    <v-progress-circular indeterminate color="grey lighten-5" />
+                  </v-layout>
+                </template>
+              </v-img>
+            </v-card>
+          </v-flex>
+          <v-flex sm6 xs12>
+            <v-card dark color="primary">
+              <v-card-text>Image 2</v-card-text>
+
+              <v-img v-if="rightImage && rightImage.link" :src="rightImage.link" @load="scrollToChoiceButtons">
+                <template v-slot:placeholder>
+                  <v-layout fill-height align-center justify-center ma-0>
+                    <v-progress-circular indeterminate color="grey lighten-5" />
+                  </v-layout>
+                </template>
+              </v-img>
+            </v-card>
+          </v-flex>
+
+
+          <!-- Experiment validation button -->
+          <v-layout justify-center align-content-center>
+            <div id="choice">
+              <v-container grid-list-md text-xs-center fluid>
+                <h2>Test {{ testCount }} / {{ maxTestCount }}</h2>
+                <v-layout row wrap>
+                  <v-flex sm6 xs12>
+                    <v-btn @click="areTheSameAction(false, getReferenceTest)" color="error" large>Images are NOT the same</v-btn>
+                  </v-flex>
+                  <v-flex sm6 xs12>
+                    <v-btn @click="areTheSameAction(true, getReferenceTest)" color="success" large>Images are the same</v-btn>
+                  </v-flex>
+                </v-layout>
+              </v-container>
+            </div>
+          </v-layout>
+          <!--/ Experiment validation button -->
+        </template>
+        <!--/ Experiment -->
+      </v-layout>
+    </v-container>
+  </div>
+</template>
+
+<script>
+import ExperimentBaseAreTheSame from '@/mixins/ExperimentBaseAreSameImages'
+import Loader from '@/components/Loader.vue'
+import experimentConfig from './config'
+
+export default {
+  name: 'ExperimentAreSameImagesRandom',
+  components: {
+    Loader
+  },
+  mixins: [ExperimentBaseAreTheSame],
+
+  data() {
+    return {
+      experimentName: 'ExperimentAreSameImagesReference'
+    }
+  },
+
+  async mounted() {
+    // Load config for this scene to local state
+    await this.loadConfig(experimentConfig)
+
+    // Load progress from store into local state
+    this.loadProgress()
+
+    // Load scene data from the API
+    await this.getQualitiesList()
+
+    // Load a test if not already one loaded
+    if (!this.leftImage || !this.leftImage.link || !this.rightImage || !this.rightImage.link) {
+      const { leftImage, rightImage } = await this.getReferenceTest()
+      this.leftImage = leftImage
+      this.rightImage = rightImage
+    }
+
+    this.saveProgress()
+  },
+
+  methods: {}
+}
+</script>

+ 3 - 1
src/views/Experiments/WithReference/index.vue

@@ -10,7 +10,9 @@
             </v-btn>
           </v-layout>
 
-          <h1>Experiment with reference - {{ sceneName }}</h1>
+          <h2>Experiment "{{ $route.meta.fullName }}"</h2>
+          <h3>{{ sceneName }}</h3>
+
           <!-- Extract configuration -->
           <extract-configuration v-if="lockConfig === false" @setExtractConfig="setExtractConfig($event, $refs.configurator)" :loading-error-message="loadingErrorMessage" ref="configurator" />
           <!--/ Extract configuration -->

+ 1 - 1
src/views/ExperimentsList.vue

@@ -60,7 +60,7 @@ export default {
   mounted() {
     this.items = Experiments.map(expe => {
       const res = {
-        name: expe.fullName,
+        name: expe.meta.fullName,
         link: `/experiments/${expe.name}`
       }
       // Check cache has an entry for each scenes in this experiment

+ 8 - 2
src/views/SelectExperimentScene.vue

@@ -7,7 +7,7 @@
       </v-btn>
     </v-layout>
 
-    Select a scene for the experiment "{{ experimentName }}"
+    Select a scene for the experiment "{{ experimentFullName }}"
 
     <v-card>
       <v-container
@@ -63,6 +63,7 @@
 
 <script>
 import { mapState, mapGetters } from 'vuex'
+import Experiments from '@/router/experiments'
 import { API_ROUTES, shuffleArray } from '@/functions'
 
 export default {
@@ -75,7 +76,8 @@ export default {
   },
   data() {
     return {
-      scenes: []
+      scenes: [],
+      experimentFullName: null
     }
   },
   computed: {
@@ -83,6 +85,10 @@ export default {
     ...mapGetters(['getHostURI'])
   },
   async mounted() {
+    // Find the selected experiment full name
+    this.experimentFullName = Experiments.find(x => x.name === this.experimentName).meta.fullName
+
+    // Order each scene by progression group, random sort in each group
     let todo = []
     let working = []
     let done = []