run.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # main imports
  2. import os
  3. import time
  4. import numpy as np
  5. import pickle
  6. # django imports
  7. from django.conf import settings
  8. # module imports
  9. from ..utils import api
  10. from ..utils.processing import crop_images
  11. from .. import config as cfg
  12. # expe imports
  13. from .classes.quest_plus import QuestPlus
  14. from .classes.quest_plus import psychometric_fun
  15. def run_quest_one_image(request, model_filepath, output_file):
  16. # 1. get session parameters
  17. qualities = request.session.get('qualities')
  18. scene_name = request.session.get('scene')
  19. expe_name = request.session.get('expe')
  20. # by default
  21. iteration = 0
  22. # used to stop when necessary
  23. if 'iteration' in request.GET:
  24. iteration = int(request.GET.get('iteration'))
  25. else:
  26. request.session['expe_started'] = False
  27. # 2. Get expe information if started
  28. # first time only init `quest`
  29. # if experiments is started we can save data
  30. if request.session.get('expe_started'):
  31. # does not change expe parameters
  32. if request.session['expe_data']['expe_previous_iteration'] == iteration:
  33. return None
  34. else:
  35. current_expe_data = request.session['expe_data']
  36. answer = int(request.GET.get('answer'))
  37. expe_answer_time = time.time() - current_expe_data['expe_answer_time']
  38. previous_percentage = current_expe_data['expe_percentage']
  39. previous_orientation = current_expe_data['expe_orientation']
  40. previous_position = current_expe_data['expe_position']
  41. previous_stim = current_expe_data['expe_stim']
  42. print("Answer time is ", expe_answer_time)
  43. # 3. Load or create Quest instance
  44. # default params
  45. # TODO : add specific thresholds information for scene
  46. thresholds = np.arange(50, 10000, 50)
  47. stim_space = np.asarray(qualities)
  48. slopes = np.arange(0.0001, 0.001, 0.00003)
  49. # check if necessary to construct `quest` object
  50. if not os.path.exists(model_filepath):
  51. qp = QuestPlus(stim_space, [thresholds, slopes], function=psychometric_fun)
  52. else:
  53. print('Load `qp` model')
  54. filehandler = open(model_filepath, 'rb')
  55. qp = pickle.load(filehandler)
  56. # 4. If expe started update and save experiments information and model
  57. # if experiments is already began
  58. if request.session.get('expe_started'):
  59. # TODO : check `i` variable
  60. # update of `quest`
  61. # qp.update(qualities[i], answer)
  62. qp.update(qualities[iteration], answer)
  63. entropy = qp.get_entropy()
  64. line = str(previous_stim)
  65. line += ";" + scene_name
  66. line += ";" + str(previous_percentage)
  67. line += ";" + str(previous_orientation)
  68. line += ";" + str(previous_position)
  69. line += ";" + str(answer)
  70. line += ";" + str(expe_answer_time)
  71. line += ";" + str(entropy)
  72. line += '\n'
  73. output_file.write(line)
  74. output_file.flush()
  75. # save `quest` model
  76. file_pi = open(model_filepath, 'wb')
  77. pickle.dump(qp, file_pi)
  78. # 5. Contruct new image and save it
  79. # construct image
  80. if iteration < cfg.expes_configuration[expe_name]['params']['iterations']:
  81. # process `quest`
  82. next_stim = qp.next_contrast()
  83. print("Next quality ", next_stim)
  84. # construct new image
  85. noisy_image = api.get_image(scene_name, next_stim)
  86. # reconstruct reference image from list stored into session
  87. ref_image = api.get_image(scene_name, 'max')
  88. img_merge, percentage, orientation, position = crop_images(noisy_image, ref_image)
  89. else:
  90. request.session['expe_finished'] = True
  91. return None
  92. # save image using user information
  93. # create output folder for tmp files if necessary
  94. tmp_folder = os.path.join(settings.MEDIA_ROOT, cfg.output_tmp_folder)
  95. if not os.path.exists(tmp_folder):
  96. os.makedirs(tmp_folder)
  97. # generate tmp merged image (pass as BytesIO was complicated..)
  98. filepath_img = os.path.join(tmp_folder, request.session.get('id') + '_' + scene_name + '' + expe_name + '.png')
  99. # replace img_merge if necessary (new iteration of expe)
  100. if img_merge is not None:
  101. img_merge.save(filepath_img)
  102. # 6. Prepare experiments data for current iteration and data for view
  103. # here you can save whatever you need for you experiments
  104. data_expe = {
  105. 'image_path': filepath_img,
  106. 'expe_percentage': percentage,
  107. 'expe_orientation': orientation,
  108. 'expe_position': position,
  109. 'expe_answer_time': time.time(),
  110. 'expe_previous_iteration': iteration,
  111. 'expe_stim': str(next_stim)
  112. }
  113. # expe is now started
  114. request.session['expe_started'] = True
  115. return data_expe