ViewOverview.py 116 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Sep 14 15:55:02 2018
  4. @author: Giovanni Galizia
  5. collects all IDL programs that were in the folder ViewOverview
  6. """
  7. # solution from https://stackoverflow.com/a/49480246
  8. if __package__ is None or __package__ == '': # if Master_Hannah2018.py is importing this file
  9. import IDL, View_gr_reports, ImageALlocal, View
  10. else: # if we are importing this file from a package, e.g., using view.idl_translation_core.ViewOverview
  11. from . import IDL, View_gr_reports, ImageALlocal, View
  12. import matplotlib as mpl
  13. mpl.use("Qt5Agg")
  14. import matplotlib.pyplot as plt
  15. import numpy as np
  16. import scipy.ndimage as sci
  17. import os
  18. import pandas as pd
  19. from moviepy.editor import VideoClip
  20. from moviepy.video.io.bindings import mplfig_to_npimage
  21. #from PIL import Image
  22. #from PIL import ImageDraw
  23. import PIL as PIL
  24. from inspect import currentframe
  25. def get_linenumber():
  26. cf = currentframe()
  27. return cf.f_back.f_lineno
  28. # I use this because singleOverviews is so convoluted, that the user should know where a message is from
  29. # print "This is line 7, python says line ", get_linenumber()
  30. def save_movie_file_xyt(dataMtrx, fps=24, bitrate="256k", movie_filename=''):
  31. # dataMtrx has shape x,y,t
  32. #start = log("save_movie_file_test2")
  33. zlen = dataMtrx.shape[2]
  34. # scale matrix to min, max
  35. scaleMin = dataMtrx.min()
  36. scaleMax = dataMtrx.max()
  37. duration = (zlen-1)/fps #frames/fps
  38. fig = plt.figure()
  39. ax = fig.add_subplot(111)
  40. fig.tight_layout(pad=1.0)
  41. dataMtrx_corrected = dataMtrx.swapaxes(0, 1)
  42. def make_frame(t):
  43. #gives frame at time t
  44. ax.clear() #without this, it is very slow
  45. ax.axis('off')
  46. ax.set_title("Frame " + str(int(zlen/duration*t)) + "/" + str(zlen))
  47. ax.imshow(dataMtrx_corrected[:,:,int(zlen/duration*t)], clim=(scaleMin, scaleMax))
  48. #fig.colorbar()
  49. return mplfig_to_npimage(fig)
  50. animation = VideoClip(make_frame, duration=duration)
  51. # export as a video file
  52. # animation.write_gif(movie_filename+'.gif', fps=fps) #gif is larger
  53. animation.write_videofile(movie_filename, fps=fps, bitrate=bitrate)
  54. plt.close()
  55. # endlog(start, "save_movie_file_xyt")
  56. def singleoverviews(flags_input,p1):
  57. '''
  58. try to translate singleoverviews from IDL in a litteral way
  59. one major change: IDL data format has multiple odors, python version uses only p1.sig1
  60. I'll try and keep the 8-bit graphic logic of IDL,
  61. and will write a separate, new graphic output routine later, once I know python better
  62. for readability, some IDL commands are kept, but not all, check file singleoverviews.pro
  63. '''
  64. # common localSingleOverviews, NextPosition ; local variable to remember last position
  65. #;Settings
  66. #PY: translate variables only if I use them - or translate them all, this need to be rewritten anyway
  67. #;CAREFUL - some settings are external flags
  68. #;some are hardwired in this program
  69. #
  70. print('ViewOverview.singleoverviews starting now')
  71. #test this:
  72. # there was a flag for flag.RM_NextPosition that is used to keep the position across iterations
  73. # does it work if I just define the variable outside, here?
  74. # bypassing the flag system?
  75. #singleoverviews is written for flags as series
  76. if isinstance(flags_input, pd.Series):
  77. flag = flags_input
  78. else:
  79. flag = flags_input.to_series()
  80. flag_RM_nextposition = flag.RM_NextPosition # (0,0)
  81. # answer: no, it does not work
  82. localVIEW_batchmode = flag.VIEW_batchmode # ? I keep it to translate literally, as fixed variable for now
  83. withinarea = flag.SO_withinArea# limit false-color output to within mask defined in .area file
  84. method = flag.SO_Method #
  85. submethod = flag.CTV_Method
  86. individualscale = flag.SO_individualScale
  87. #IF not localBatchMode THEN print,'indiScale ', individualscale, ', method: ', method, ', CTV: ',subMethod
  88. centerimage2zero = individualscale // 10 #all values up to 9 do not center scale image
  89. individualscale = individualscale % 10
  90. percentilescale = 0
  91. indiscale3factor = 0.2 #; set to 0.2 for 20 % border to be ignored when scaling usind idividualscale eq 3
  92. if ((individualscale > 100) and (individualscale < 200)):# then begin
  93. indiscale3factor = (individualscale-100)/100.0 #; set to 0.2 (i.e. 120 for individualscale) for 20 % border to be ignored when scaling usind idividualscale eq 3
  94. individualscale = 3
  95. #endIF
  96. if ((individualscale > 1000) and (individualscale < 2000)):# then begin
  97. percentilevalue = (individualscale % 100)/100.0
  98. percentilescale = 1
  99. individualscale = (individualscale % 1000) // 100
  100. #; 1xyy, x gives individualscale
  101. indiscale3factor= 0.2 #; set to 0.2 for 20 % border to be ignored when scaling usind idividualscale eq 3
  102. #endIF
  103. newcolumn = flag.RM_NewColumn # temporary: standard to 1 for old setup
  104. #setup = fix(flag[LE_loadExp])
  105. markcoordinates = flag.RM_FotoOk #]) ;if set, includes a black square at the glomeruli chosen
  106. # ;if set to 2, includes the TIFF file xxx.tiff
  107. # ;3 for both 1 and 2
  108. # ;4 for 1 filled with glomerulus value
  109. # ;5 for show perimeter
  110. shrinkfactor = flag.LE_ShrinkFaktor
  111. #separateLayers = fix(flag[RM_separateLayers]) ;if set, gives the coordinates only in the correct layer specified in the list
  112. #
  113. annotatefactor = 100 #; factor to multiply minimum and maximum with when annotating
  114. #markBorder = 1 ; marks the border of each overview in fixed color, set to 0 for 13
  115. #flipSides = fix(flag[RM_differentViews])
  116. # ; if 0 then no flipSides, if above 0 gives the position within p1.viewLabel which shows the side
  117. # ; for example, if p1.viewLable is 'BR' and flipSides is '2', 'R' is extracted and the image is flipped
  118. # ; (R indicating right AL, and therefore the need to swap sides)
  119. # ; In these instances, the frame around the images is colour coding the sides too.
  120. # ; swapping up/down for sideway ALs, use 'D' (derecha) as a code
  121. border = 10 # ; border to leave in exportTIFFcanvas
  122. drawscalebar = flag.CTV_scalebar#])
  123. unsharpmaskfilter = flag.RM_unsharpmask #
  124. unsharpmasksize = 20 #;fix(flag[RM_PrintAscii])
  125. unsharpmasksize2 = 10
  126. #
  127. #;morphoThreshold Flags now in its own routine
  128. #default: everything off
  129. #
  130. #;controls for FlipSide:
  131. flipframe = 0 #; default value
  132. #PY: flipSides not implemented
  133. #IF flipSides gt 0 then begin
  134. # IF ((strmid(p1.viewLabel,flipSides-1,1) eq 'R') or (strmid(p1.viewLabel,flipSides-1,1) eq 'r')) THEN begin ;rignt side, flip sides
  135. # flipFrame = 1
  136. # endIF
  137. # IF ((strmid(p1.viewLabel,flipSides-1,1) eq 'D') or (strmid(p1.viewLabel,flipSides-1,1) eq 'd')) THEN begin ;rignt side, flip sides
  138. # flipFrame = 2
  139. # endIF
  140. #endIF
  141. #
  142. ##PY: font control not set
  143. #;font control
  144. #!P.FONT=1
  145. #DEVICE, SET_FONT='Helvetica', /TT_FONT, SET_CHARACTER_SIZE=[8,8]
  146. #
  147. exportTIFFcanvas = 0
  148. markborder = 0
  149. flipsides = 0
  150. exportTIFFframe = 0
  151. if localVIEW_batchmode:# THEN begin
  152. if flag.VIEW_ReportMethod == 10:
  153. exportTIFFcanvas = 1
  154. # exportTIFFcanvas = 1
  155. # endIF
  156. elif (flag.VIEW_ReportMethod in [13,20]):
  157. exportTIFFcanvas = 2
  158. markborder = 0
  159. # IF ((fix(flag[VIEW_ReportMethod]) eq 13) or (fix(flag[VIEW_ReportMethod]) eq 20)) THEN begin
  160. # exportTIFFcanvas = 2
  161. # markBorder = 0
  162. # endIF
  163. elif (flag.VIEW_ReportMethod in [14]):
  164. exportTIFFcanvas = 3
  165. markborder = 0
  166. flipsides = 0
  167. # IF fix(flag[VIEW_ReportMethod]) eq 14 THEN begin
  168. # exportTIFFcanvas = 3
  169. # markBorder = 0
  170. # flipsides = 0
  171. # endIF
  172. elif (flag.VIEW_ReportMethod in [15]):
  173. exportTIFFcanvas = 0
  174. markborder = 0
  175. flipsides = 0
  176. exportTIFFframe = 1
  177. # IF fix(flag[VIEW_ReportMethod]) eq 15 THEN begin
  178. # exportTIFFcanvas = 0
  179. # markBorder = 0
  180. # flipsides = 0
  181. # exportTIFFframe = 1
  182. # endIF
  183. elif (flag.VIEW_ReportMethod in [21]):
  184. exportTIFFcanvas = 4
  185. ############# this is treated as exportTIFFcanvas 1 for now. check singleoverviews.pro if this turns out to be a problem
  186. # IF fix(flag[VIEW_ReportMethod]) eq 21 THEN begin
  187. # exportTIFFcanvas = 4
  188. # endIF
  189. #endIF
  190. #
  191. #
  192. #
  193. if unsharpmaskfilter:
  194. print('********* Using unsharp mask in SingleOverviews!! ***********************************************')
  195. print('not advised - I need to check the maths, because high frequency noise is deleterious')
  196. #
  197. radius = flag.RM_Radius
  198. #
  199. #
  200. #IF fix(flag[trueColour]) THEN begin
  201. # if fix(flag[macSystem]) THEN device, /true_color
  202. # device, decomposed=0
  203. #endIF
  204. #
  205. #; use values from control window
  206. startframe = flag.CTV_firstframe #in IDL, this was flag.CTV_firstframe only (without CTV)
  207. endframe = flag.CTV_lastframe #in IDL, this was flag.flastframe only (without CTV)
  208. maximum = flag.SO_MV_scalemax
  209. minimum = flag.SO_MV_scalemin
  210. #
  211. zoomfactor = 1
  212. #
  213. ############# maybe here variables are over ############
  214. # frame = np.zeros([p1.format_x, p1.format_y])
  215. #frame(*,*) = -1000 ; borders are black; find other solution in python
  216. #
  217. ###PY: there is only one buffer.
  218. #lastbuffer = p1.odors
  219. #;display 'first buffer' or not?
  220. #firstBuffer = fix(flag[LE_UseFirstBuffer])
  221. #IF (firstBuffer lt 0) THEN begin ; guess whether to use the first buffer on the basis of the setup
  222. # ;IF correctFlag eq 0 THEN firstbuffer = 1 ELSE firstBuffer = 0
  223. # IF setup eq 0 THEN firstBuffer = 0 ; for old setup, show also air control
  224. # IF setup eq 3 THEN firstBuffer = 1 ; for TILL, do not show AIR control
  225. # IF setup eq 4 THEN firstBuffer = 1 ; for TILL, do not show AIR control
  226. # IF (fix(flag[VIEW_ReportMethod]) eq 20) THEN firstBuffer = 1
  227. # IF (fix(flag[VIEW_ReportMethod]) eq 20) THEN lastBuffer = 1
  228. # ; if air was subtracted for correction then leave air overview away - it is 0 !
  229. # ;this is not really appropriate when using corrected dataset - just used for backwards compatibility
  230. # if (max(sig1(*,*,0,0)) eq 0) and (min(sig1(*,*,0,0)) eq 0) then firstbuffer = 1
  231. #endIF
  232. #numOdours = lastbuffer - firstBuffer + 1
  233. #
  234. #min1 = fltARR(2)
  235. #max1 = fltARR(2)
  236. #;minimum = 10000
  237. #;maximum = -10000
  238. # PY I skip individualscale 2, since that is for several odors
  239. #if (individualScale eq 2) then begin ;scale to min/max of all frames, takes more time
  240. # for odor = firstbuffer, lastbuffer do begin
  241. # overviewframe = overview( odor, method )
  242. # min1(0) = min(overviewframe)
  243. # max1(0) = max(overviewframe)
  244. # minimum = min(min1)
  245. # maximum = max(max1)
  246. # min1(1) = minimum
  247. # max1(1) = maximum
  248. # endFor
  249. #endif
  250. #
  251. if (individualscale == 0): scalestring = ' ' + str(flag.SO_MV_scalemin) + '/' + str(flag.SO_MV_scalemax) +' '
  252. elif individualscale == 1: scalestring = ' indSc '
  253. elif individualscale == 2: scalestring = ' ' + str(minimum) + '/' + str(maximum) +' '
  254. elif individualscale == 3: scalestring = ' SindSc '
  255. elif individualscale == 5: scalestring = ' P5Sc '
  256. elif individualscale == 6: scalestring = ' P6Sc '
  257. elif individualscale == 7: scalestring = ' P7Sc '
  258. else: scalestring = ' P'+str(centerimage2zero)+str(individualscale)+'Sc '
  259. if (method == 2): borderstring = ': start=' + str(startframe+1) + ', end=' + str(endframe+1)
  260. else: borderstring = ': '
  261. #
  262. # fenstertitel = p1.experiment + borderstring+scalestring + ', M=' + str(method) +'/'+str(submethod)
  263. # fenstertitel = p1.ex_name + borderstring+scalestring + ', M=' + str(method) +'/'+str(submethod)
  264. #
  265. #IF not localBatchMode Then window, /free, xsize = ( (p1.format_x) * zoomfactor), $
  266. # ysize = p1.format_y * zoomfactor, title = Fenstertitel
  267. #
  268. if exportTIFFframe:
  269. if localVIEW_batchmode:
  270. outfile = flag.STG_OdorReportPath # this is not the file, but the folder
  271. else:
  272. outCanvasFile = IDL.dialog_pickfile(flag.STG_OdorReportPath,'TIF_'+p1.metadata.ex_name,write=True,defaultextension='tif')
  273. # ELSE outFile = dialog_pickfile(/WRITE, path=flag[stg_odorReportPath],file='TIF_'+p1.experiment)
  274. # tvlct, r, g, b, /get
  275. #end
  276. #
  277. #;write TIFF canvas
  278. if (exportTIFFcanvas >= 1):# THEN begin
  279. # ;get filename of file to write canvas to
  280. if localVIEW_batchmode:
  281. outCanvasFile = os.path.join(flag.STG_OdorReportPath, flag.STG_ReportTag)#] $
  282. else:
  283. outCanvasFile = IDL.dialog_pickfile(flag.STG_OdorReportPath,'',write=True,defaultextension='tif')
  284. #outCanvasFile = dialog_pickfile(/write, path=flag[stg_odorReportPath])
  285. #return
  286. # tvlct, r, g, b, /get
  287. #ENDIF
  288. if (exportTIFFcanvas == 1): outCanvasFile = outCanvasFile +'.tif'
  289. elif (exportTIFFcanvas == 2): outCanvasFile = outCanvasFile +'_3D.tif'
  290. elif (exportTIFFcanvas == 3): outCanvasFile = outCanvasFile +'_3D.raw'
  291. elif (exportTIFFcanvas == 4): outCanvasFile = outCanvasFile +'.tif'
  292. if (exportTIFFcanvas in [1,4]):
  293. # 4 is multilayered, with odors side by side, but in python there is only one odor, therefore
  294. # combine exportTIFFcanvas 1 and 4 here
  295. # ;check if preexisting file: YES read file, NO create array
  296. # openR, 1, outCanvasFile, ERROR = err; err eq 0 if file exists
  297. # IF ( err eq 0 ) THEN begin ; file exists already
  298. # close, 1 ; reclose file
  299. if os.path.isfile(outCanvasFile):
  300. TIFFcanvas, (R,G,B) = IDL.read_tiff(outCanvasFile) #use plt.imsave to save
  301. print('read file and palette: ', outCanvasFile)
  302. # TIFFcanvas = read_tiff(outCanvasFile, R, G, B)
  303. xySizeCanvas = TIFFcanvas.shape
  304. # xySizeCanvas = size(TIFFcanvas, /dimensions) ;xySize(0) contains x, (1) the y dimension
  305. if not localVIEW_batchmode:
  306. # if localVIEW_batchmode:
  307. print(__file__,': testing color map plasma')
  308. plt.imshow(TIFFcanvas, cmap='plasma')
  309. # IF not localBatchMode THEN begin
  310. # tvlct, r, g, b
  311. # tv, TiffCanvas
  312. # endIF
  313. if newcolumn:
  314. # ;add a column to the TIFF canvas, and allow for more rows if necessary
  315. dummy_row_size = max([xySizeCanvas[0],(p1.metadata.format_x+2*border)]) # x values
  316. dummy_col_size = xySizeCanvas[1]+p1.metadata.format_y+border
  317. # byte type in python/numpy is 'uint8'
  318. dummy = IDL.bytarr(dummy_row_size,dummy_col_size)
  319. dummy[0:xySizeCanvas[0],0:xySizeCanvas[1]] = TIFFcanvas
  320. TIFFcanvas = dummy
  321. flag_RM_nextposition = (border, xySizeCanvas[1]) #tuple with rows,columns values
  322. print('ViewOverview.singleoverviews: Next frame (new column) to be placed at: ',flag_RM_nextposition)
  323. print('...TIFFcanvas size is: ',TIFFcanvas.shape)
  324. flag.RM_NewColumn = 0 #switch off newcolumn
  325. else: #ENDif ELSE begin; not newColumn
  326. # ;not a new column, but a new frame at the bottom of the old column, so chech whether canvas is long enough
  327. # ;therefore, either the length (xySizeCanvas(1) is sufficient,
  328. # ;or take Nextposition + p1.formaty (multiplied by the frames necessary)
  329. ####NextPosition is a global variable!!! put into flags: flag_RM_nextposition
  330. # therefore position needs not to change here yet
  331. dummy_row_size = max([xySizeCanvas[0],flag_RM_nextposition[0]+p1.metadata.format_x+border])
  332. dummy_col_size = max([xySizeCanvas[1],flag_RM_nextposition[1]+p1.metadata.format_y+border]) #rows
  333. dummy = IDL.bytarr(dummy_row_size,dummy_col_size)
  334. dummy[0:xySizeCanvas[0],0:xySizeCanvas[1]] = TIFFcanvas
  335. TIFFcanvas = dummy
  336. print('ViewOverview.singleoverviews: Next frame (not new column) to be placed at: ',flag_RM_nextposition)
  337. print('...TIFFcanvas size is: ',TIFFcanvas.shape)
  338. # ENDELSE ; newColumn
  339. else: #new file# ENDIF else BEGIN ;create new canvas, add frame of border on each side
  340. TIFFcanvas = IDL.bytarr(p1.metadata.format_x+(2*border), p1.metadata.format_y+2*border)
  341. flag_RM_nextposition = [border,border] #;for right positioning of new data, see below
  342. # END
  343. #endIF
  344. #
  345. # if (exportTIFFcanvas == 4): ##############merged with exportTIFFcanvas == 1
  346. #IF (exportTiffCanvas eq 4) THEN begin
  347. # ;check if preexisting file: YES read file, NO create array
  348. # IF existfile(outCanvasFile) THEN begin
  349. # if os.path.isfile(outCanvasFile):
  350. # TIFFcanvas = read_tiff(outCanvasFile, R, G, B)
  351. # xySizeCanvas = size(TIFFcanvas, /dimensions) ;xySize(0) contains x, (1) the y dimension
  352. # IF not localBatchMode THEN begin
  353. # tvlct, r, g, b
  354. # tv, TiffCanvas
  355. # endIF
  356. # IF newColumn THEN begin
  357. # ;add a column to the TIFF canvas, and allow for more rows if necessary
  358. # ;since with wxportTiffCanvas multiple odours are given sidewise, y is only increased by one frame
  359. # ;but x is increased by the number of odours
  360. # dummyYsize = MAX([xySizeCanvas(1),(p1.metadata.format_y+border)+border])
  361. # dummy = bytARR((xySizeCanvas(0)+numodours*(p1.metadata.format_x+border)),dummyysize)
  362. # dummy(0:xySizeCanvas(0)-1,0:xySizeCanvas(1)-1) = TIFFcanvas
  363. # TIFFcanvas = dummy
  364. # NextPosition = xySizeCanvas ;to make sure the definition of NextPosition is correct copy both values
  365. # NextPosition(1) = border ; start the new column from the top
  366. # ENDif ELSE begin; not newColumn
  367. # ;not a new column, but a new frame at the bottom of the old column, so chech whether canvas is long enough
  368. # ;therefore, either the length (xySizeCanvas(1) is sufficient,
  369. # ;or take Nextposition + p1.formaty (multiplied by the frames necessary)
  370. # dummyYsize = MAX([xySizeCanvas(1),Nextposition(1)+(p1.format_y+border)])
  371. # dummyXsize = MAX([xySizeCanvas(0),Nextposition(0)+numodours*(p1.format_x+border)])
  372. # dummy = bytARR(dummyXsize,dummyysize)
  373. # dummy(0:xySizeCanvas(0)-1,0:xySizeCanvas(1)-1) = TIFFcanvas
  374. # TIFFcanvas = dummy
  375. # ENDELSE ; newColumn
  376. # ENDIF else BEGIN ;create new canvas, add frame of border on each side
  377. # TIFFcanvas = bytARR(p1.format_x*numodours+((numodours+1)*border), (p1.format_y+border)+border)
  378. # nextPosition = [border,border] ;for right positioning of new data, see below
  379. # END
  380. #endIF
  381. #
  382. #;****
  383. if (exportTIFFcanvas in [1,4]):
  384. # ;annotate canvas
  385. newsizecanvas = TIFFcanvas.shape
  386. windowSize = (newsizecanvas[1],newsizecanvas[0])
  387. #IDL window: Create graphics window number 10 with a size of x by y pixels and a title that reads TITLE:
  388. ### python: create PIL window
  389. mode = 'P' #(8-bit pixels, mapped to any other mode using a color palette
  390. window10 = PIL.Image.new(mode, windowSize) #creates an image into object window10
  391. # window, 10, xsize=newSizeCanvas(0), ysize=newSizeCanvas(1), TITLE='TextForTiffCanvas', /PIXMAP, RETAIN=2 ;pixmap makes the window invisible
  392. # ;window, 10, xsize=newSizeCanvas(0), ysize=newSizeCanvas(1), TITLE='TextForTiffCanvas', RETAIN=2 ;pixmap makes the window invisible
  393. #endIF
  394. #
  395. #;correct the radius value if shrinkfactor is ste
  396. if shrinkfactor not in [0,1]:
  397. radius = radius / shrinkfactor
  398. #endIF
  399. #
  400. #
  401. #;go through all odours and calculate the overview frame
  402. #for odor = firstbuffer, lastbuffer do begin
  403. ##in python, there is only one odor
  404. #
  405. #;*********************THIS is where the false-color picture is calculated************
  406. overviewframe = overview(p1, flag, method)
  407. # axes swapped to compensate for axis swapping by imshow
  408. # but swapping is not working in IDLoff mode, removed 27.7.19
  409. # overviewframe = overviewframe.swapaxes(0, 1)
  410. # without swapping, overviewframe has the right shape.
  411. #;*********************all that follows is additional information************
  412. #
  413. if unsharpmaskfilter: # THEN begin
  414. print('ViewOverview.singleoverviews: unsharpmaskfilter with fixed settings - check' )
  415. print('does not work, because smooth creates values that are too small - needs a smooth or median on the original data')
  416. overviewframe = 2 * overviewframe - IDL.smooth(overviewframe, unsharpmasksize)
  417. # overviewFrame = 2*overviewframe - smooth(overviewframe, unsharpmasksize, /edge_truncate)
  418. if (unsharpmasksize2 > 0): overviewframe = 2*overviewframe - IDL.smooth(overviewframe, unsharpmasksize2)
  419. # endIF
  420. #
  421. #
  422. if (individualscale == 1):
  423. if percentilescale:
  424. minimum = np.percentile(overviewframe, 100*percentilevalue)
  425. maximum = np.percentile(overviewframe, 100-100*percentilevalue)
  426. else:
  427. minimum = np.min(overviewframe)
  428. maximum = np.max(overviewframe)
  429. elif (individualscale == 3): # then begin ;take min and max only from central region
  430. if percentilescale:
  431. minimum = np.percentile(overviewframe[round(indiscale3factor*p1.metadata.format_x):round((1-indiscale3factor)*p1.metadata.format_x) ,
  432. round(indiscale3factor*p1.metadata.format_y):round((1-indiscale3factor)*p1.metadata.format_y)], 100*percentilevalue)
  433. maximum = np.percentile(overviewframe[round(indiscale3factor*p1.metadata.format_x):round((1-indiscale3factor)*p1.metadata.format_x) ,
  434. round(indiscale3factor*p1.metadata.format_y):round((1-indiscale3factor)*p1.metadata.format_y)], 100-100*percentilevalue)
  435. # maximum = percentile(overviewframe((indiScale3factor*p1.format_x):((1-indiScale3factor)*p1.format_x),(indiScale3factor*p1.format_y):((1-indiScale3factor)*p1.format_y)),1-percentileValue)
  436. else:
  437. minimum = np.min(overviewframe[round(indiscale3factor*p1.metadata.format_x):round((1-indiscale3factor)*p1.metadata.format_x) ,
  438. round(indiscale3factor*p1.metadata.format_y):round((1-indiscale3factor)*p1.metadata.format_y)])
  439. maximum = np.max(overviewframe[round(indiscale3factor*p1.metadata.format_x):round((1-indiscale3factor)*p1.metadata.format_x) ,
  440. round(indiscale3factor*p1.metadata.format_y):round((1-indiscale3factor)*p1.metadata.format_y)])
  441. # minimum = min(overviewframe((indiScale3factor*p1.format_x):((1-indiScale3factor)*p1.format_x),(indiScale3factor*p1.format_y):((1-indiScale3factor)*p1.format_y)))
  442. # maximum = max(overviewframe((indiScale3factor*p1.format_x):((1-indiScale3factor)*p1.format_x),(indiScale3factor*p1.format_y):((1-indiScale3factor)*p1.format_y)))
  443. # endELSE
  444. # endif
  445. elif (individualscale in [5,6,7]):
  446. # if ((individualScale ge 5) and (individualScale le 7)) then begin
  447. # ;scale with min and max of selected region
  448. # ;restore the selected region
  449. # ;5: min max from region
  450. # ;6 and 7, identical: min fixed, max from region (6 and 7 differ in exportmovie)
  451. # ;get selected AL area
  452. # IF (fix(flag[RM_differentViews]) gt 0) THEN begin
  453. # ;special section Tilman
  454. # ;areaFileName = flag[stg_OdorMaskPath]+strmid(Flag[stg_ReportTag],0,14)+p1.viewLabel+' '+strmid(Flag[stg_ReportTag],14)+'.area'
  455. # ;standard section
  456. # areaFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+p1.viewLabel+'.Area'
  457. # endIF else begin
  458. # areaFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+'.Area'
  459. # endELSE
  460. # OPENR, 1, areafilename, ERROR = err ;Try to open the file demo.dat.
  461. # IF (err NE 0) then begin
  462. # print, 'Looking for file: ',areafilename
  463. # areaFileName = Dialog_Pickfile(Path=flag[stg_OdorMaskPath], get_Path = inPath, Filter='*.Area', title='Choose perimeter file (or cancel and correct program)!')
  464. # flag[stg_OdorMaskPath] = inpath
  465. # endIF else begin
  466. # close, 1 ; file exists, all ok
  467. # endELSE
  468. # restore, areaFileName
  469. maskframe = IDL.restore_maskframe(flag) #restores maskframe from file
  470. # ;now AL perimeter is in variable 'maskframe'
  471. # ;correct for unequal size array ######## removed, since dummy is not used later
  472. # dummy = overviewframe # ; get same size array
  473. # dummy[:]=0
  474. # xtop = min( maskframe.shape[0], dummy.shape[0] )
  475. # ytop = min( maskframe.shape[1], dummy.shape[1] )
  476. ## ytop = min([(size(maskframe))(2),(size(dummy))(2)] ) -1
  477. # dummy[0:xtop,0:ytop] = maskframe[0:xtop,0:ytop]
  478. # ;shift maskframe
  479. maskframe = np.roll(maskframe, (p1.shiftX/shrinkfactor, p1.shiftY/shrinkfactor), axis=(1,0)) #in numpy, vertical is first
  480. # maskframe = shift(maskframe, p1.shiftX/shrinkFactor, p1.shiftY/shrinkFactor)
  481. # ;now AL perimeter is in variable maskframe
  482. positions = maskframe > 0 # where(maskframe)
  483. if percentilescale: #THEN begin
  484. if (individualscale == 5):
  485. minimum = np.percentile(overviewframe[positions],100*percentilevalue)
  486. maximum = np.percentile(overviewframe[positions],100-100*percentilevalue)
  487. # maximum = percentile(overviewframe(positions),1-percentileValue)
  488. # endIF else begin
  489. else:
  490. if (individualscale == 5):
  491. minimum = np.min(overviewframe[positions])
  492. maximum = np.max(overviewframe[positions])
  493. # if (individualScale eq 5) then minimum = min(overviewframe(positions))
  494. # maximum = max(overviewframe(positions))
  495. # endELSE
  496. # endIF ;indiscale 5
  497. # ;******************************
  498. # ********* end individual scale
  499. # ;adjust min/max if centerImage is selected to be symmetrical around 0, irrespective of indiscl
  500. if (centerimage2zero == 2): # then begin ;center the image at 0, simmetrically
  501. maximum = max([abs(minimum),abs(maximum)])
  502. minimum = -maximum
  503. # endIF
  504. # ;cut image above maximum and below minimum
  505. overviewframe = np.clip(overviewframe, minimum, maximum)
  506. # overviewframe = overviewframe < maximum
  507. # overviewframe = overviewframe > minimum
  508. # ;redefine maximum and minimum in order to avoid black and white in the false-color image
  509. setmaximum = (maximum + (maximum - minimum)/253.0)
  510. setminimum = (minimum - (maximum - minimum)/253.0)
  511. #
  512. #; IF ((exportTIFFcanvas eq 1) or (exportTIFFcanvas eq 4)) then BEGIN ;annotate min and max on the canvas
  513. #; xyouts, NextPosition(0)+p1.format_x+border-2, NewSizeCanvas(1)-NextPosition(1)-p1.format_y, strTrim(string(fix(minimum*annotateFactor)),2), /device, ALIGNMENT=0, ORIENTATION=90
  514. #### analysis#; xyouts,
  515. # x coordinate: NextPosition(0)+p1.format_x+border-2,
  516. # y coordinate: NewSizeCanvas(1)-NextPosition(1)-p1.format_y,
  517. # text2write: strTrim(string(fix(minimum*annotateFactor)),2),
  518. # where to write: /device,
  519. # ALIGNMENT=0, #0 means left alignment
  520. # ORIENTATION=90 #90 means vertical going up
  521. #; xyouts, NextPosition(0)+p1.format_x+border-2, NewSizeCanvas(1)-NextPosition(1), strTrim(string(fix(maximum*annotateFactor)),2), /device, ALIGNMENT=1, ORIENTATION=90
  522. #; print, 'min max in singleoverviews is ',minimum, maximum
  523. #; ENDif
  524. # endif
  525. # ;annotate the used minimum and maximum on the canvas
  526. if (exportTIFFcanvas in [1,4]):
  527. # IF ((exportTIFFcanvas eq 1) or (exportTIFFcanvas eq 4)) then BEGIN ;annotate min and max on the canvas
  528. # window10 = IDL.xyouts(flag_RM_nextposition[0]+p1.format_x, newsizecanvas[1]-flag_RM_nextposition[1]-p1.format_y,
  529. # str(int(round(minimum*annotatefactor))),
  530. # window10, orientation=90, fill=255, align='left')
  531. odortext = ImageALlocal.localodortext(flag, p1)
  532. mintext = str(int(round(minimum*annotatefactor)))
  533. maxtext = str(int(round(maximum*annotatefactor)))
  534. window10 = IDL.xyouts(flag_RM_nextposition[1]+p1.metadata.format_y,
  535. flag_RM_nextposition[0]+p1.metadata.format_x+border,
  536. odortext,
  537. window10, orientation=0, fill=255, align='right')
  538. window10 = IDL.xyouts(flag_RM_nextposition[1]+p1.metadata.format_y, #place in the image to the right
  539. flag_RM_nextposition[0], #place in the image down
  540. mintext,
  541. window10, orientation=90, fill=255, align='left')
  542. # xyouts, NextPosition(0)+p1.format_x+border-2, NewSizeCanvas(1)-NextPosition(1)-p1.format_y, strTrim(string(fix(minimum*annotateFactor)),2), /device, ALIGNMENT=0, ORIENTATION=90, color=254
  543. window10 = IDL.xyouts(flag_RM_nextposition[1]+p1.metadata.format_y,
  544. flag_RM_nextposition[0]+p1.metadata.format_x,
  545. maxtext,
  546. window10, orientation=90, fill=255, align='right')
  547. # xyouts, NextPosition(0)+p1.metadata.format_x+border-2, NewSizeCanvas(1)-NextPosition(1),
  548. # strTrim(string(fix(maximum*annotateFactor)),2), /device, ALIGNMENT=1, ORIENTATION=90, color=254
  549. print('ViewOverview.singleoverviews line ',get_linenumber(),': canvas annotated with min max ',minimum, maximum)
  550. print(' as: ',mintext, maxtext)
  551. if (centerimage2zero > 0):
  552. window10 = IDL.xyouts(flag_RM_nextposition[1]+p1.metadata.format_y,
  553. flag_RM_nextposition[0]+round(0.5 * p1.metadata.format_x),
  554. '0',
  555. window10, orientation=90, fill=255, align='center')
  556. #THEN xyouts, NextPosition(0)+p1.format_x+border-2, NewSizeCanvas(1)-NextPosition(1)-fix(0.5*p1.format_y), strTrim('0',2), /device, ALIGNMENT=0, ORIENTATION=90, color=254
  557. if newcolumn: #only if new column there is space to write something
  558. window10 = IDL.xyouts(flag_RM_nextposition[1], flag_RM_nextposition[0],
  559. p1.experiment[0:10],
  560. window10, orientation = 0, fill=255, align='left') #IDL orientation was 1
  561. # ENDif
  562. #
  563. #
  564. #
  565. #;remove data outside mask if so wanted
  566. if withinarea: # then begin
  567. # IF (fix(flag[RM_differentViews]) gt 0) THEN begin
  568. # areaFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+p1.viewLabel+'.Area'
  569. # endIF else begin
  570. # areaFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+'.Area'
  571. # endELSE
  572. # OPENR, 1, areafilename, ERROR = err ;Try to open the file demo.dat.
  573. # IF (err NE 0) then begin
  574. # print, 'Looking for file: ',areaFileName
  575. # areaFileName = Dialog_Pickfile(Path=flag[stg_OdorMaskPath], get_Path = inPath, Filter='*.Area', title='Choose perimeter file (or cancel and correct program)!')
  576. # flag[stg_OdorMaskPath] = inpath
  577. # endIF else begin
  578. # close, 1 ; file exists, all ok
  579. # endELSE
  580. # restore, areaFileName
  581. maskframe = IDL.restore_maskframe(flag) #restores maskframe from file
  582. # ;now AL perimeter is in variable 'maskframe'
  583. # ;correct for unequal size array
  584. # dummy = overviewframe ; get same size array
  585. # dummy(*)=0
  586. # xtop = min([(size(maskframe))(1),(size(dummy))(1)] ) -1
  587. # ytop = min([(size(maskframe))(2),(size(dummy))(2)] ) -1
  588. # dummy(0:xtop,0:ytop) = maskframe(0:xtop,0:ytop)
  589. # ;shift maskframe
  590. # maskframe = shift(maskframe, p1.shiftX/shrinkFactor, p1.shiftY/shrinkFactor)
  591. # AreaPositions = where(maskframe eq 0) ;remember Area Positions for MorphoBackground
  592. # overviewFrame(Areapositions) = setminimum
  593. # endIF
  594. # dummy = overviewframe # ; get same size array ########## removed since dummy is not used later
  595. # dummy[:]=0
  596. # xtop = min( maskframe.shape[0], dummy.shape[0] )
  597. # ytop = min( maskframe.shape[1], dummy.shape[1] )
  598. ## ytop = min([(size(maskframe))(2),(size(dummy))(2)] ) -1
  599. # dummy[0:xtop,0:ytop] = maskframe[0:xtop,0:ytop]
  600. # ;shift maskframe
  601. maskframe = np.roll(maskframe, (p1.shiftX/shrinkfactor, p1.shiftY/shrinkfactor), axis=(1,0)) #in numpy, vertical is first
  602. overviewframe[maskframe == 0] = setminimum
  603. #
  604. #
  605. # ;odorText enth‰lt Text, der unterhalb des Bildes ist
  606. # ;odorText = p1.ex_name + '_' + p1.treatment + '_' + strtrim(string(fix(p1.treat_conc *10)),2) ; neue Listen
  607. # odortext = ImageALlocal.localodortext(flag, p1)
  608. # ;odorText = p1.odor(odor) + '_' +strTrim(string(p1.odor_nr(1)),2)
  609. # ;odorText = p1.odor(odor) + '_' +strTrim(p1.viewLabel,2)
  610. # ;odorText = p1.ex_name + '_' + strmid(p1.treatment,0,1);vom treatment nur der erste buchstabe
  611. # if (exportTIFFcanvas in [1,4]):
  612. # IF ((exportTIFFcanvas eq 1) or (exportTIFFcanvas eq 4)) then BEGIN ;annotate odortext on the canvas
  613. # xyouts, Nextposition(0)+p1.format_x, NewSizeCanvas(1)-NextPosition(1)-p1.format_y-border,odorText, /device, ALIGNMENT=1, color=254
  614. # window10 = IDL.xyouts(flag_RM_nextposition[1]+p1.format_y,
  615. # flag_RM_nextposition[0]+p1.format_x+border,
  616. # odortext,
  617. # window10, orientation=0, fill=254, align='right')
  618. # ENDIF
  619. #
  620. #
  621. #
  622. # ;mark the chosen glomeruli in the frame
  623. if markcoordinates in [1,3,4]:
  624. print('ViewOverview.singleoverviews: marking coordinates')
  625. # IF fix(flag[RM_differentViews]) THEN begin
  626. # readListe, GlomeruliNum, liste, flag[stg_OdorMaskPath]+flag[stg_ReportTag]+p1.viewLabel+'.coor' , column4=separateLayers
  627. # endIF else begin
  628. # readListe, GlomeruliNum, liste, flag[stg_OdorMaskPath]+flag[stg_ReportTag]+'.coor', column4=separateLayers
  629. # endELSE
  630. liste = View_gr_reports.read_glo_liste(flag, p1)
  631. # liste = View_gr_reports.readListe(flag,p1)
  632. # go through glomeruli. That is not the computationally fastest way, but easier to read
  633. # ;delete overviewframe for markcoordinates eq 4
  634. if markcoordinates == 4:
  635. overviewframe[:] = 0
  636. setminimum = 0
  637. setmaximum = 255
  638. # IF (markcoordinates eq 4) THEN begin
  639. # overviewframe(*)=0
  640. # Setminimum = 0
  641. # Setmaximum = 255
  642. # endIF
  643. # IF (markCoordinates eq 1 ) THEN markValue = Setmaximum ELSE markValue = Setminimum
  644. #changed logic to 3, because in the case of 4 we need maximum
  645. if markcoordinates == 3:
  646. markvalue = setminimum
  647. else:
  648. markvalue = setmaximum
  649. ######the following (shift and shrink) is in readliste now
  650. # for index, row in liste.iterrows():
  651. # print('Now glomerulus ',index, row)
  652. # row.x_glo = row.x_glo + p1.shiftX
  653. # row.y_glo = row.y_glo + p1.shiftY
  654. ## ;shiftMaskeX, shiftMaske
  655. ## liste(0,*) = liste(0,*) + p1.shiftX
  656. ## liste(1,*) = liste(1,*) + p1.shiftY
  657. ## ;consider shrinkfactor
  658. ## IF (shrinkFactor gt 1) then begin
  659. # if (flag.LE_ShrinkFaktor > 1): #no shrinking below 1?
  660. # row.x_glo = row.x_glo / flag.LE_ShrinkFaktor
  661. # row.y_glo = row.y_glo / flag.LE_ShrinkFaktor
  662. ## liste(0,*) = liste(0,*)/shrinkFactor
  663. ## liste(1,*) = liste(1,*)/shrinkFactor
  664. # endIF
  665. # ;now mark the relative positions
  666. for index, row in liste.iterrows():
  667. # for i=0,GlomeruliNum-1 do begin
  668. # ;only draw the right layer if separateLayers is checked
  669. # if separateLayers THEN begin
  670. # IF (odor eq liste(3,i)) THEN drawCoordinate = 1 ELSE drawCoordinate = 0
  671. # endIF else drawCoordinate = 1
  672. #
  673. # IF drawCoordinate then begin
  674. # ;mark position liste(0),liste(1), would be frame2(liste(0),liste(1))
  675. leftborder = max(row.x_glo-radius,0)
  676. rightborder = min(row.x_glo+radius,p1.metadata.format_x-1)
  677. topborder = max(row.y_glo-radius,0)
  678. bottomborder= min(row.y_glo+radius,p1.metadata.format_y-1)
  679. # leftborder = MAX([liste(0,i)-radius,0])
  680. # rightborder = MIN([liste(0,i)+radius,p1.format_x-1])
  681. # topborder = MAX([liste(1,i)-radius,0])
  682. # bottomborder = MIN([liste(1,i)+radius,p1.format_y-1])
  683. # ;wenn er hier aussteigt, dann ist eine Koordinate mitsamt Rahmen total aus dem Bild verschwunden!
  684. overviewframe[leftborder : rightborder, topborder ]=markvalue
  685. overviewframe[leftborder : rightborder, bottomborder ]=markvalue
  686. overviewframe[leftborder , topborder : bottomborder ]=markvalue
  687. overviewframe[rightborder, topborder : bottomborder ]=markvalue
  688. # IF (markCoordinates eq 4) THEN begin ;color fill the glomeruli squares
  689. # fillvalue = liste(2,i) < 244 ; only byte values allowed
  690. if markcoordinates == 4:
  691. overviewframe[leftborder+1:rightborder,topborder+1:bottomborder] = row.num_glo
  692. # endIF
  693. # endIF
  694. # endfor
  695. # ENDIF ; markCoordinates
  696. # ;overlay an external TIFF file
  697. # ;this 'maske' file needs to be a greyscale tiff, only values of 0 (black) are taken
  698. elif markcoordinates in [2,3]:
  699. print('ViewOverview.singleoverviews ',get_linenumber(),': overlay external tiff file not yet implemented ******************* ')
  700. # IF ((markCoordinates eq 2) OR (markCoordinates eq 3 ) ) THEN begin
  701. # IF fix(flag[RM_differentViews]) THEN begin
  702. # maske = read_tiff(flag[stg_OdorMaskPath]+flag[stg_ReportTag]+p1.viewLabel+'.tif');
  703. # endIF else begin
  704. # maske = read_tiff(flag[stg_OdorMaskPath]+flag[stg_ReportTag]+'.tif');
  705. # endELSE
  706. # maske = shift(maske, p1.shiftX, p1.shiftY)
  707. # xsizemaske = fix((size(maske))(1)/shrinkFactor)
  708. # ysizemaske = fix((size(maske))(2)/shrinkFactor)
  709. # IF (shrinkFactor gt 1) then begin
  710. # maske = rebin( maske(0:xsizemaske*shrinkFactor-1, 0:ysizemaske*shrinkFactor-1), xsizemaske,ysizemaske)
  711. # maske = (maske > 200) - 200
  712. # print, 'Maske rescaled in singleoverviews.pro after shrinkFactor correction'
  713. # endIF
  714. # for xi=0, min([xsizemaske,p1.format_x])-1 do begin
  715. # for yi=0, min([ysizemaske,p1.format_y])-1 do begin
  716. # IF (maske(xi,yi) eq 0) THEN overviewframe(xi,yi) = Setmaximum
  717. # endFOR
  718. # endFOR
  719. # endIF
  720. elif markcoordinates in [5]:
  721. print('ViewOverview.singleoverviews ',get_linenumber(),': overlay markCoordinates 5 not implemented yet ******************* ')
  722. # IF ((markCoordinates eq 5 )) THEN begin
  723. # IF fix(flag[RM_differentViews]) THEN begin
  724. # areaFile = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+p1.viewLabel+'.area'
  725. # endIF else begin
  726. # areaFile = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+'.area'
  727. # endELSE
  728. # restore, areafile ;restores variable maskframe
  729. # maske = shift(maskframe, p1.shiftX, p1.shiftY)
  730. # xsizemaske = fix((size(maske))(1)/shrinkFactor)
  731. # ysizemaske = fix((size(maske))(2)/shrinkFactor)
  732. # IF (shrinkFactor gt 1) then begin
  733. # maske = rebin( maske(0:xsizemaske*shrinkFactor-1, 0:ysizemaske*shrinkFactor-1), xsizemaske,ysizemaske)
  734. # print, 'Maske rescaled in singleoverviews.pro after shrinkFactor correction'
  735. # endIF
  736. # maske = roberts(maske) ; edge-detection
  737. # maske = dilate(maske,REPLICATE(1, 2,2))
  738. # maske = bytscl(maske)
  739. #
  740. # for xi=0, min([xsizemaske,p1.format_x])-1 do begin
  741. # for yi=0, min([ysizemaske,p1.format_y])-1 do begin
  742. # IF (maske(xi,yi) gt 200) THEN overviewframe(xi,yi) = Setmaximum
  743. # endFOR
  744. # endFOR
  745. # endIF
  746. #
  747. #
  748. # ;mark the border of the whole frame
  749. if markborder:
  750. markvalue = setmaximum #;default value
  751. if (flipsides > 0): # THEN begin
  752. if flipframe: # THEN begin ; right side, green color is about a third of the colour scale
  753. markvalue = setminimum + ((setmaximum - setminimum)/3.0)
  754. else: # begin ;left side
  755. markvalue = setmaximum - ((setmaximum - setminimum) / 250.0)
  756. overviewframe[0 ,:] = markvalue
  757. overviewframe[-1,:] = markvalue
  758. overviewframe[: ,0] = markvalue
  759. overviewframe[: ,-1] = markvalue
  760. # overviewframe(*,0)=markValue
  761. # overviewframe(p1.format_x-1,*)=markValue
  762. # overviewframe(*,p1.format_y-1)=markValue
  763. # ENDIF ; markBorder
  764. # ;mark the border of the whole frame if unsharp mask is on
  765. if unsharpmaskfilter: # THEN begin
  766. markvalue = setmaximum - ((setmaximum - setminimum)/3.0)
  767. overviewframe[0 ,:] = markvalue
  768. overviewframe[-1,:] = markvalue
  769. overviewframe[: ,0] = markvalue
  770. overviewframe[: ,-1] = markvalue
  771. overviewframe[0 , int(p1.metadata.format_y/3):int(2*p1.metadata.format_y/3)] = setminimum
  772. overviewframe[int(p1.metadata.format_x/3):int(2*p1.metadata.format_x/3) , 0] = setmaximum
  773. overviewframe[-1 , int(p1.metadata.format_y/3) : int(2*p1.metadata.format_y/3)] = setminimum
  774. overviewframe[int(p1.metadata.format_x/3):int(2*p1.metadata.format_x/3),-1] = setmaximum
  775. # endIF
  776. #
  777. ###################
  778. # copy overviewframe to frame2, scale to bytes
  779. ###################
  780. # ;scale image to byte range
  781. if ((centerimage2zero == 0) or (centerimage2zero == 2)): #THEN begin
  782. # ;scale image to byte
  783. frame2 = IDL.bytscl(overviewframe, MIN=setminimum, MAX=setmaximum)#, TOP=!d.table_size)
  784. print('SingleOverviews ',get_linenumber(),', Image scaled to min, max: ', setminimum, setmaximum)
  785. # endIF
  786. elif (centerimage2zero == 1): # THEN begin
  787. # ;if centerImage2zero is 1, range from 0 to max and from 0 to min are scaled independently!
  788. # ;if centerImage2zero is 2, scaling is equal for top and bottom range, below
  789. frameup = IDL.bytscl(overviewframe, MIN=0, MAX=setmaximum)#, TOP=!d.table_size)
  790. framedown = IDL.bytscl(overviewframe, MIN=setminimum, MAX=0 )# TOP=!d.table_size)
  791. if (setminimum >= 0): framedown[:] = 255
  792. frame2 = (framedown/2 + frameup/2).astype('uint8')
  793. # ;frame2 = frame2 < 254
  794. frame2 = np.clip(frame2,1,255)
  795. print('SingleOverviews ',get_linenumber(),', Image scaled to min, ctr, max: ', setminimum, '; 0; ', setmaximum)
  796. # endIF
  797. elif (centerimage2zero == 3):
  798. # ;if centerImage2zero is 1, range from 0 to max and from 0 to min are scaled independently!
  799. # ;if centerImage2zero is 2, scaling is equal for top and bottom range, below
  800. # ;if centerImage2zero is 3, range from 0 to max and from 0 to min are scaled independently! 0 is at 1/4 of the scale ()
  801. frameup = IDL.bytscl(overviewframe, MIN=0, MAX=setmaximum)#, TOP=!d.table_size)
  802. framedown = IDL.bytscl(overviewframe, MIN=setminimum, MAX=0)#, TOP=!d.table_size)
  803. if (setminimum >= 0):
  804. framedown[:] = 255
  805. frame2 = (framedown/4.0 + 3*frameup/4.0).astype('uint8')
  806. # ;because of the rescaling, some pixels can get the value 0 now, and appear black in a colorscale with black bottom
  807. # ;just put these pixels to 1
  808. # ;frame2 = frame2 < 254
  809. frame2 = np.clip(frame2,1,255)
  810. print('SingleOverviews ',get_linenumber(),', Image scaled to min, ctr, max: ', setminimum, '; 0; ', setmaximum)
  811. # endIF
  812. else:
  813. print('Singleoverviews ',get_linenumber(),': centerimage2zero with unexpected value')
  814. #else
  815. # ;morphoThreshold
  816. print('SingleOverviews: Morphothreshold not implemented yet')
  817. # MorphoThreshold256, frame2, withinMask, Areapositions, r, g, b
  818. #
  819. #
  820. # ;zoom image
  821. if zoomfactor != 1:
  822. frame2 = IDL.rebin(frame2, (p1.metadata.format_x) * zoomfactor, p1.metadata.format_y * zoomfactor, sample = 1)
  823. #this rebin destroyed the image in my test run - but I don't know why
  824. #
  825. # ;flip sides if right AL
  826. # IF (flipFrame eq 1) THEN frame2 = rotate(frame2,5) #flip on the vertical axis
  827. if (flipframe == 1): frame2 = np.fliplr(frame2)
  828. if (flipframe == 2): frame2 = np.flipud(frame2) #rotate 7
  829. #
  830. if not localVIEW_batchmode:
  831. ## show image in VIEWgui
  832. #img = PIL.Image.fromarray(frame2) #, 'RGB')
  833. #im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255)) from https://stackoverflow.com/questions/10965417/how-to-convert-numpy-array-to-pil-image-applying-matplotlib-colormap
  834. #img = PIL.Image.fromarray(cm.gist_earth(frame2).set_clim(0,255)))
  835. ct_IDLpalette = IDL.createPalette(flag.SO_MV_colortable)
  836. #print('ViewOverview - loaded palette ',flag.SO_MV_colortable)
  837. #img.show()
  838. # in view-gui use plt, not PIL -
  839. if not plt.isinteractive():
  840. plt.ion()
  841. plt.figure()
  842. #plt.imshow(frame2.T, cmap=ct_IDLpalette, vmin=100, vmax=200, origin='bottom')
  843. print('ViewOverview.singleovervies line ',get_linenumber(),': frame2 has values ranging from ',
  844. np.min(frame2), np.max(frame2))
  845. plt.imshow(frame2.T, cmap=ct_IDLpalette, origin='bottom', vmin=0, vmax=255)
  846. #I scale 0-255, since bytscl has done the scaling to bytes before
  847. plt.title('Better not save from VIEWgui - run VIEWoff')
  848. plt.draw()
  849. # plt.show(block=False)
  850. #https://matplotlib.org/3.1.0/tutorials/colors/colormap-manipulation.html
  851. #TODO add color map here
  852. if exportTIFFframe:
  853. tifffilename = os.path.join(outfile,ImageALlocal.localodortext(flag, p1) + '.tif')
  854. #img has not been created yet!
  855. #def write_tiff(outfile, MyArray, red, green, blue, xresol=100, yresol=100):
  856. IDL.write_tiff(tifffilename, frame2, R, G, B)
  857. # write_tiff, outFile+LocalOdorText(p1,odor)+'.tif', frame2, red=r, blue=b, green=g
  858. print('Singleoverviews: Written tiff to ',tifffilename)
  859. # endIF
  860. #
  861. if exportTIFFcanvas in [1,4]:
  862. # IF (exportTIFFcanvas eq 1) THEN begin
  863. # ;copy frame2 to the right position of the canvas
  864. # ;TIFFcanvas(nextPosition(0):nextPosition(0)+p1.format_x-1, NextPosition(1)+(odor-firstbuffer)*(p1.format_y+border): NextPosition(1)-border+(odor-firstbuffer+1)*(p1.format_y+border)-1)=frame2
  865. # ;die obere Zeile mit der nächsten ersetzt, als bei der Alten Anlage die berechnung mehrerer Bilder untereinander f¸r einen 4er Block nicht ging, Nov 1999
  866. # TIFFcanvas(nextPosition(0):nextPosition(0)+p1.format_x-1, NextPosition(1): NextPosition(1)+p1.format_y-1)=frame2
  867. TIFFcanvas[flag_RM_nextposition[0]:flag_RM_nextposition[0]+p1.metadata.format_x,
  868. flag_RM_nextposition[1]:flag_RM_nextposition[1]+p1.metadata.format_y] = frame2
  869. flag_RM_nextposition = (flag_RM_nextposition[0]+p1.metadata.format_x+border,flag_RM_nextposition[1])
  870. # NextPosition(1) = NextPosition(1) + border + p1.format_y
  871. print('Remember and write to flags: New Nextposition is ',flag_RM_nextposition)
  872. flags_input.update_flags({'RM_NextPosition': flag_RM_nextposition})
  873. #flag.RM_NextPosition = flag_RM_nextposition
  874. # ENDif ; exportTIFFcanvas
  875. # IF (exportTIFFcanvas eq 2) THEN begin
  876. elif (exportTIFFcanvas == 2): # THEN begin
  877. # tvlct, r, g, b ##this gives the color table to the display.
  878. # if I understand this correctly, IDL tv is like PIL imshow
  879. # tv, frame2
  880. plt.imshow(frame2)
  881. # write_tiff, outCanvasFile, frame2, red=r, blue=b, green=g, /append
  882. # ;NextPosition(1) = NextPosition(1) + border + p1.format_y
  883. print('not implemented yet: frame written to multilayered TIFF ',outCanvasFile)
  884. #TODO
  885. #return NotImplemented
  886. # ENDif ; exportTIFFcanvas
  887. elif (exportTIFFcanvas == 3):
  888. print('ViewOverview.Singleoverviews: exportTIFFcanvas 3 not implemented yet')
  889. # IF (exportTIFFcanvas eq 3) THEN begin
  890. # ;write_raw_frame, outCanvasFile, frame2
  891. # write_raw_frame, outCanvasFile, overviewframe, p1, odor ;export raw and not scaled data
  892. # ;NextPosition(1) = NextPosition(1) + border + p1.format_y
  893. # print, 'frame written to multilayered raw file ',outCanvasFile
  894. # ENDif ; exportTIFFcanvas
  895. #endfor ;odor
  896. #
  897. #; draw scalebar
  898. #IF drawScalebar THEN begin
  899. if (drawscalebar):
  900. print('ViewOverview.Singleoverviews: drawscalebar')
  901. scalebar = np.tile(np.arange(p1.metadata.format_x*zoomfactor),(31,1)) #create array with repeated elements, 31 pixels wide
  902. # scaleBar = INTARR(31,p1.format_y*zoomfactor)
  903. # scale = reverse(indgen(p1.format_y*zoomfactor))
  904. # for i=0,30 do scaleBar(i,*) = scale(*)
  905. # IF ((setminimum lt 0) and (setmaximum gt 0)) THEN begin ;mark 0 position
  906. if (setminimum < 0) & (setmaximum > 0):
  907. if centerimage2zero == 3:
  908. # IF (centerImage2zero eq 3) THEN begin
  909. # ;level = (3*p1.format_y*zoomfactor/4)
  910. level = 0.75 * p1.metadata.format_x*zoomfactor
  911. # level = 0.75*p1.format_y*zoomfactor
  912. # endIF else BEGIN
  913. else:
  914. # level = p1.format_x*zoomfactor - p1.format_x*zoomfactor*setminimum / (setminimum - setmaximum)
  915. level = p1.metadata.format_x*zoomfactor*setminimum / (setminimum - setmaximum)
  916. # level = p1.format_y*zoomfactor-p1.format_y*zoomfactor*(setminimum/(setminimum - setmaximum))
  917. # endELSE
  918. # scaleBar(*,fix(level))=0
  919. scalebar[:,int(level)] = 0
  920. # endIF
  921. scalebar = IDL.bytscl(scalebar, MIN=np.min(scalebar), MAX=np.max(scalebar))
  922. # scaleBar = bytscl(scaleBar)
  923. #################output moved down
  924. # IF not localBatchMode Then tv, bytscl(scaleBar, MIN=0, MAX=p1.format_y*zoomfactor, TOP=!d.table_size), 0
  925. # IF exportTIFFframe THEN write_tiff, outFile+'ScaleBar', scalebar, red=r, blue=b, green=g
  926. # IF (exportTIFFcanvas eq 1) THEN write_tiff, outCanvasFile+'ScaleBar', scalebar, red=r, blue=b, green=g
  927. # print, 'written scalebar'
  928. # ;or do a scale bar by hand:
  929. # ;loadct, SO_MV_colortable
  930. # ;tvlct, r, g, b, /get
  931. # ;scale = BINDGEN(256)
  932. # ;scalebar = intArr(31,256)
  933. # ;for i=0,30 do scalebar(i,*) = scale(*)
  934. # ;filename = dialog_pickfile(/write)
  935. # ;write_tiff, filename, scalebar, red=r, blue=b, green=g
  936. #ENDif
  937. #
  938. #
  939. #
  940. #
  941. #;save CANVAS
  942. if exportTIFFcanvas in [1, 4]: # THEN begin
  943. # ;annotate canvas
  944. # ;write title
  945. # if newcolumn: #only if new column there is space to write something
  946. # window10 = IDL.xyouts(newsizecanvas[0]-border, newsizecanvas[1],
  947. # p1.experiment[0:10],
  948. # window10, orientation = 0, fill=254, align='right') #IDL orientation was 1
  949. # ;write names for single odours
  950. # for odor = firstbuffer, lastbuffer do begin
  951. # ;xyouts, newsizeCanvas(0)-border, newSizeCanvas(1)-border+1-(((odor-firstbuffer)+1)*(p1.format_y+border)), p1.odor(odor), /device, ALIGNMENT=1
  952. # endfor
  953. # ;now get annotated image from screen
  954. # ;************here we have a frequent graphics problem - call Giovanni if that happens again
  955. # ;NewText = tvRD(/true)
  956. # ;NewText = tvRD()
  957. #
  958. # ;the next two lines for 8 bit screen
  959. # ;NewText = tvRD(channel=3) ;set at KN:Picasso because of 24bit screen - may not work on other computers
  960. # ;NewTextIndices = where(NewText lt 128, count)
  961. #
  962. # ;also: in IDL -> FILE -> PREFERENCES -> Graphics set backing store to bitmap buffered.
  963. #
  964. # ;alternatively, the next two lines for 24 bit screen
  965. # ;NewText = tvRD(channel=1) ;set at KN:set to 1 for 8 bit screen
  966. # ;NewTextIndices = where(NewText gt 128, count)
  967. #
  968. # ;new, hopefully automatic version, october 2010
  969. # device, get_visual_depth=depth ;ask for bit depth of screen
  970. # IF (depth eq 24) THEN begin
  971. # NewText = tvRD(channel=1) ;
  972. # NewTextIndices = where(NewText gt 128, count)
  973. # endif else begin
  974. # NewText = tvRD(channel=3) ;
  975. # NewTextIndices = where(NewText lt 128, count)
  976. # endelse
  977. #
  978. newText = np.asarray(window10) #get array with all text
  979. # newText = np.swapaxes(newText, 0, 1)
  980. TIFFcanvas[newText>128] = 255 # copy this into canvas
  981. # ;therefore the next line
  982. # print, '**** IF TIFF FILES ARE BLANK, then! '
  983. # print, 'overviews/Singleoverviews.pro: tvRD set to channel=1 or not; if there is no image change the line before here'
  984. # ; 'If it does not work, try retain keyword to 2 in preferences-graphics-backing store; see ?tvrd'
  985. # ; it may also be that the next line should be gt 128 instead of lt 128
  986. #
  987. # if (count gt 0) then TiffCanvas(NewTextIndices) = 255
  988. # ;get necessary resolution for A4
  989. longSide = max(newsizecanvas[0:1]) #;11.693 inches is 29.7 cm, 10,118 is 25.7 cm
  990. shortSide = min(newsizecanvas[0:1]) #;8.268 inches is 21 cm, 6.695 inches is 17 cm
  991. A4resolution = max([longSide/10.118,shortSide/6.695])
  992. # create palette
  993. ct_IDLpalette = IDL.createPalette(flag.SO_MV_colortable)#flag.SO_MV_colortable)
  994. #because of the way I have written IDL.write_tiff, for now I need to extract R,G,B
  995. #because I have written IDL.createPalette twice, with different logic. Too bad...
  996. #R, G, B = IDL.createPalette(flag.SO_MV_colortable)
  997. R, G, B = IDL.palette_pyplot2PIL(ct_IDLpalette)
  998. print('ViewOverview: created palette using: ',flag.SO_MV_colortable)
  999. # ctP = ct_IDLpalette(np.linspace(0,1,256))
  1000. # #R is in ctP[:,0]
  1001. # R = ctP[:,0]*255
  1002. # G = ctP[:,1]*255
  1003. # B = ctP[:,2]*255
  1004. #IDL.write_tiff(outCanvasFile, TIFFcanvas, R, G, B, A4resolution, A4resolution)
  1005. IDL.write_tiff(outCanvasFile, TIFFcanvas, R,G,B, A4resolution, A4resolution)
  1006. if drawscalebar:
  1007. IDL.write_tiff(outCanvasFile+'_scb.tif', scalebar, R, G, B)#, A4resolution, A4resolution)
  1008. #question: what happened to window10? Why did I need that?
  1009. # window10.save(outCanvasFile)
  1010. # write_tiff, outCanvasFile, TIFFCanvas, red=r, blue=b, green=g, xresol=A4resolution, yresol=A4resolution
  1011. # ;IF not localBatchMode THEN begin
  1012. # window, 11, xsize=newSizeCanvas(0), ysize=newSizeCanvas(1), TITLE='TIFFcanvas'
  1013. # tvlct, r, g, b
  1014. # tv, TiffCanvas
  1015. # print, 'Canvas written to file ',outCanvasFile
  1016. # ;endIF
  1017. #endIF
  1018. #
  1019. #;reset color table
  1020. #loadct, SO_MV_colortable
  1021. #
  1022. #odor=1
  1023. #
  1024. #end
  1025. #remember
  1026. # flags_input.update_flags({'RM_NextPosition': flag_RM_nextposition})
  1027. print('ViewOverview.singleoverviews done')
  1028. # returns the flags object whenever possible
  1029. return flags_input
  1030. #; of program singleoverviews
  1031. def overview(p1, flag, method):
  1032. if method == 0:
  1033. overviewframe = overview0ctv(p1, flag)
  1034. elif method == 10:
  1035. overviewframe = overview10ctv(p1, flag)
  1036. else:
  1037. print('ViewOverview.overview: method not yet considered in python (19.9.2018)')
  1038. #
  1039. #IF correctFlag eq 0 THEN signals = sig1 ELSE signals = sig1corr
  1040. #filter = 1
  1041. #filtersize = 5
  1042. #startframe = firstframe
  1043. #endframe = lastframe
  1044. #method = fix(method) ;this line is needed because flags are defined as strings
  1045. #CASE method OF
  1046. # 0: BEGIN
  1047. # OverviewFrame = Overview0CTV(odorNum)
  1048. # END
  1049. # 1: BEGIN
  1050. # OverviewFrame = Overview1Sum(signals, odorNum, filter, filtersize, startframe, endframe, p1)
  1051. # END
  1052. # 2: BEGIN
  1053. # OverviewFrame = Overview2Diff(signals, odorNum, filter, filtersize, startframe, endframe,p1)
  1054. # END
  1055. # 3: BEGIN
  1056. # OverviewFrame = Overview3Max(signals, odorNum, filter, filtersize, startframe, endframe,p1)
  1057. # END
  1058. # 4: BEGIN
  1059. # OverviewFrame = Overview4Contrast(signals, odorNum, filter, filtersize, startframe, endframe,p1)
  1060. # END
  1061. # 5: BEGIN
  1062. # OverviewFrame = Overview5Silke(signals, odorNum, filter, filtersize, startframe, endframe,p1)
  1063. # END
  1064. # 6: BEGIN
  1065. # OverviewFrame = Overview6VisiAM(signals, odorNum, filter, filtersize, startframe, endframe,p1)
  1066. # END
  1067. # 7: BEGIN
  1068. # OverviewFrame = Overview7max9_19(signals, odorNum, filter, filtersize, startframe, endframe,p1)
  1069. # END
  1070. # 8: BEGIN
  1071. # OverviewFrame = Overview8mean(signals, odorNum, filter, filtersize, startframe, endframe,p1)
  1072. # END
  1073. # 10: BEGIN
  1074. # OverviewFrame = Overview10CTV(odorNum)
  1075. # END
  1076. # 11: BEGIN
  1077. # OverviewFrame = Overview11correlate(signals,odorNum)
  1078. # END
  1079. # 12: BEGIN
  1080. # OverviewFrame = Overview12long_correlate(signals,p1.odors)
  1081. # END
  1082. # ELSE: text = dialog_message('WARNING: wrong method in Overview.pro, set flag[so_method]')
  1083. #ENDCASE
  1084. return overviewframe
  1085. def overview0ctv(p1, flag):
  1086. '''
  1087. apply curve2value to every single pixel in the frame - slow
  1088. '''
  1089. print('ViewOverview.overview0ctv not implemented yet in python (19.9.2018)')
  1090. overviewframe = 0
  1091. return overviewframe
  1092. def overview10ctv(p1, flag):
  1093. '''
  1094. calculate overview frame from a calculation on frames, rather than time traces
  1095. therefore, functions in curve2value have to be repeated here, with some delicacy
  1096. faster than overview0ctv.
  1097. Not all cases were implemented in python - when needed, work on ViewOverview.overview10ctv
  1098. '''
  1099. CTVmethod = flag.CTV_Method
  1100. #;externalized CTVs are:
  1101. #;values below 0 go to personal Overview10CTVLocal in ImageALLocal folder
  1102. #IF (CTVmethod lt 0) THEN OverviewFrame=Overview10CTVLocal(odorNum)
  1103. if CTVmethod < 0:
  1104. print('ViewOverview.overview10ctv does not implement flag.CTV_Method < 0, i.e. Overview10CTVLocal')
  1105. return
  1106. #;values above 1000 go to Overview10CTVMathias in ImageALMathias folder
  1107. #IF (CTVmethod gt 1000) THEN OverviewFrame=CurveToValueMathias(odorNum)
  1108. if CTVmethod > 1000:
  1109. print('ViewOverview.overview10ctv does not implement flag.CTV_Method > 0, i.e. CurveToValueMathias')
  1110. return
  1111. #;poor old Giovanni only has values between 0 and 999 (1000 is lost in ...)
  1112. #IF (CTVmethod ge 0) AND (CTVmethod le 1000) THEN begin
  1113. TIMEfilter = flag.Signal_FilterTimeFlag #;aus common vars
  1114. SPACEfilter = flag.Signal_FilterSpaceFlag
  1115. overviewFrame = IDL.fltarr(p1.metadata.format_x,p1.metadata.format_y)
  1116. #;INPUT IS SIG1corr(x,y,*,odorNum) or sig1(x,y,*,odornum)
  1117. #IF correctFlag then begin
  1118. # dummy = sig1corr(*,*,*,odorNUM)
  1119. #end ELSE BEGIN
  1120. dummy = p1.sig1.copy()
  1121. #end
  1122. #;remove spurious dimension
  1123. #dummy = reform(dummy)
  1124. #;apply time filter - makes no sense
  1125. if TIMEfilter: #dummy = smooth(dummy, Signal_FilterTimeSize)
  1126. print('ViewOverview.overview10ctv timefilter implemented differently from IDL version')
  1127. # in IDL, the filter was applied to all three dimension - but a time filter should only work on time
  1128. dummy = IDL.smooth(dummy, [0,0,flag.Signal_FilterTimeSize])
  1129. #;define masks for influence of each frame onto the final image
  1130. maskFactor = np.zeros(p1.metadata.frames, dtype=np.float32)
  1131. firstframe = flag.CTV_firstframe #this was just firstframe in IDL
  1132. lastframe = flag.CTV_lastframe
  1133. #CASE fix(flag[ctv_method]) OF $ ;calculate with same values as CTV
  1134. if CTVmethod == 12:
  1135. # 12 : begin
  1136. # ; from CurveToValue result = TOTAL(curve(firstFrame:lastFrame)) ;total between values in control window
  1137. maskFactor[firstframe:lastframe+1]= 1.0/(lastframe+1-firstframe)
  1138. # end
  1139. elif CTVmethod == 20: # begin
  1140. maskFactor[lastframe]=1.0
  1141. maskFactor[firstframe]=-1.0
  1142. # end
  1143. # 21 : begin
  1144. # maskFactor(p1.stimulus_on+2:p1.stimulus_on+4)=1.0/3
  1145. # maskFactor(p1.stimulus_on-3:p1.stimulus_on-1)=-1.0/3
  1146. # end
  1147. # ;22: mean of 3 frames around lastframe - mean of 3 frames around firstframe
  1148. # ;22 : overviewFrame(*,*) = total((dummy(*,*,lastframe-1:lastframe+1) - dummy(*,*,firstframe-1:firstframe+1)),3)/3
  1149. elif CTVmethod == 22 :
  1150. maskFactor[lastframe-1:lastframe+2] = 1.0/3
  1151. maskFactor[firstframe-1:firstframe+2] =-1.0/3
  1152. # end
  1153. # 23 : begin
  1154. # maskFactor(p1.stimulus_on+2:p1.stimulus_on+3*p1.frequency) = +1/(3*p1.frequency)
  1155. # maskFactor(p1.stimulus_on-3*p1.frequency:p1.stimulus_on-1) = -1/(3*p1.frequency)
  1156. # end
  1157. # ;24: mean of 3 frames 1 sec after stimOnset, - mean of 3 frames before stimOnset
  1158. # ;24 : overviewFrame(*,*) = (TOTAL(dummy(*,*,p1.stimulus_on+p1.frequency-1:p1.stimulus_on+p1.frequency+1),3) - TOTAL(dummy(*,*,p1.stimulus_on-3:p1.stimulus_on-1),3))/3
  1159. # 24 : begin
  1160. # maskFactor(p1.stimulus_on+p1.frequency-1:p1.stimulus_on+p1.frequency+1)=1.0/3
  1161. # maskFactor(p1.stimulus_on-3:p1.stimulus_on-1)= -1.0/3
  1162. # end
  1163. # 25 : begin
  1164. # maskFactor(lastframe-1:lastframe+1)=1.0/3
  1165. # maskFactor(firstframe-7:firstframe+1)=-1.0/9
  1166. # end
  1167. # 26 : begin ; Paul 11.12.01
  1168. # maskFactor(lastframe:lastframe+14)=1.0/15
  1169. # maskFactor(firstframe:firstframe+4)=-1.0/5
  1170. # end
  1171. # 27 : begin ; Paul 11.12.01
  1172. # maskFactor(lastframe:lastframe+2)=1.0/3
  1173. # maskFactor(firstframe:firstframe+4)=-1.0/5
  1174. # end
  1175. # ;35 first find max of the overall average response within the 3 seconds after the stimulus
  1176. # ;then take mean around this max (3frames) - mean of 3 frames before stimulus
  1177. # ;this is similar, BUT NOT IDENTICAL to method 35 in CTV, because there the maximum is in each pixel position separatedly
  1178. elif CTVmethod == 35 :
  1179. singleCurve = np.mean(dummy, axis = (0,1)) # total(total(dummy,1),1)
  1180. position = p1.metadata.stimulus_on + np.argmax(singleCurve[p1.metadata.stimulus_on:p1.metadata.stimulus_on+int(3*p1.frequency)])
  1181. ###this returns the FIRST maximum
  1182. # position = p1.stimulus_on + position
  1183. print('ViewOverview.Overview10CTV: Maximum frame in this measurement was ',position)
  1184. maskFactor[position-1:position+2]=1.0/3
  1185. maskFactor[p1.metadata.stimulus_on-3:p1.metadata.stimulus_on]=-1.0/3
  1186. # end;35
  1187. # 38 : begin ;daniela, get GLOBAL maximum between 2 and 5, subtract mean of 0-1 from that frame
  1188. # singleCurve = total(total(dummy,1),1)
  1189. # maxPos = max(singleCurve(2:5), position)
  1190. # position = position+2
  1191. # print, 'Maximum frame in this measurement was ',position
  1192. # maskfactor(position)=1.0
  1193. # maskfactor(0:1)=-1.0/2
  1194. # end
  1195. # 50 : begin ;einstellungen fr Andre, ândern sich noch
  1196. # maskFactor(p1.stimulus_on+2:p1.stimulus_on+4)=1.0/3
  1197. # maskFactor(p1.stimulus_on-3:p1.stimulus_on-1)=-1.0/6
  1198. # maskFactor(p1.stimulus_on-3+p1.frequency*6:p1.stimulus_on-1+p1.frequency*6)=-1.0/6
  1199. # end
  1200. # 51 : begin ;einstellungen fr Andre, ândern sich noch
  1201. # maskFactor(11:13) = 1.0/3
  1202. # maskFactor(6:8) =-1.0/6
  1203. # maskFactor(24:26) =-1.0/6
  1204. # end
  1205. # 100 : begin
  1206. # maskFactor(0:2)=-1.0/3
  1207. # maskFactor(4:8)=1.0/5
  1208. # end
  1209. # 151 : begin
  1210. # maskFactor(0)= -1.0/3
  1211. # maskFactor(3)= -1.0/3
  1212. # maskFactor(6)= -1.0/3
  1213. # maskFactor(9)= 1.0/3
  1214. # maskFactor(12)= 1.0/3
  1215. # maskFactor(15)= 1.0/3
  1216. # end
  1217. # 152 : begin
  1218. # maskFactor(1)= -1.0/3
  1219. # maskFactor(4)= -1.0/3
  1220. # maskFactor(7)= -1.0/3
  1221. # maskFactor(10)= 1.0/3
  1222. # maskFactor(13)= 1.0/3
  1223. # maskFactor(16)= 1.0/3
  1224. # end
  1225. # 153 : begin
  1226. # maskFactor(2)= -1.0/3
  1227. # maskFactor(5)= -1.0/3
  1228. # maskFactor(8)= -1.0/3
  1229. # maskFactor(11)= 1.0/3
  1230. # maskFactor(14)= 1.0/3
  1231. # maskFactor(17)= 1.0/3
  1232. # end
  1233. # 161 : begin
  1234. # maskFactor(0:1)=-1.0/2
  1235. # maskFactor(2) =1.0
  1236. # end
  1237. # 162 : begin
  1238. # maskFactor(0:1)=-1.0/2
  1239. # maskFactor(3) =1.0
  1240. # end
  1241. # 163 : begin
  1242. # maskFactor(0:1)=-1.0/2
  1243. # maskFactor(4) =1.0
  1244. # end
  1245. # 164 : begin
  1246. # maskFactor(0:1)=-1.0/2
  1247. # maskFactor(5) =1.0
  1248. # end
  1249. # 165 : begin
  1250. # maskFactor(0:2)=-1.0/3
  1251. # maskFactor(3) =1.0
  1252. # end
  1253. # 166 : begin
  1254. # maskFactor(0:2)=-1.0/3
  1255. # maskFactor(4) =1.0
  1256. # end
  1257. # 167 : begin
  1258. # maskFactor(0:2)=-1.0/3
  1259. # maskFactor(5) =1.0
  1260. # end
  1261. # 300 : maskfactor(*) = 1.0/p1.frames
  1262. # 301: maskfactor(5:10)=1.0/6
  1263. # 302: maskfactor(p1.stimulus_on:p1.stimulus_on+2)=1.0/3
  1264. # 303: maskfactor(p1.stimulus_on-3:p1.stimulus_on)=1.0/4
  1265. #
  1266. # 322 : begin
  1267. # maskFactor(lastframe-1:lastframe+1)=1.0/3
  1268. # end
  1269. # 335 : begin
  1270. # singleCurve = total(total(dummy,1),1)
  1271. # maxPos = max(singleCurve(p1.stimulus_on:p1.stimulus_on+3*p1.frequency), position)
  1272. # position = p1.stimulus_on + position
  1273. # print, 'Maximum frame in this measurement was ',position
  1274. # maskfactor(position-1:position+1)=1.0/3
  1275. # end;35
  1276. #
  1277. #
  1278. # ;values above 500 now used for analyzing repetitive stimulation
  1279. # 524 : begin
  1280. # ;takes the three frames around one second after each stimulus as extimated max
  1281. # ;then sums activity after each next stimulus, and subtracts activity before each next stimulus
  1282. # ;the first stimulus is excluded from the analysis
  1283. # ;find place of first maximum
  1284. # maxShift = p1.frequency-1
  1285. # ;interstimulus interval is p1.stimulus_isi, skip first response
  1286. # position = p1.stimulus_on + p1.stimulus_isi ;next stimulus position
  1287. # IF (p1.stimulus_isi gt 0) then begin
  1288. # while ((position+Maxshift+1) lt (p1.frames-1)) do begin
  1289. # maskfactor(position+Maxshift-1:position+Maxshift+1)=1.0/3
  1290. # maskfactor(position-3:position-1)=-1.0/3
  1291. # position = position + p1.stimulus_isi ; move to the next stimulus
  1292. # endWhile
  1293. # endIF
  1294. # end
  1295. # 535 : begin
  1296. # ;first calculates the delay between stimulus onset and response maximum using the first response
  1297. # ;then sums activity after each next stimulus, and subtracts activity before each next stimulus
  1298. # ;the first stimulus is excluded from the analysis
  1299. # ;find place of first maximum
  1300. # singleCurve = total(total(dummy,1),1)
  1301. # maxPos = max(singleCurve(p1.stimulus_on:p1.stimulus_on+3*p1.frequency), MaxShift)
  1302. # print, 'Maximum frame in this measurement was ',p1.stimulus_on + MaxShift
  1303. # ;interstimulus interval is p1.stimulus_isi
  1304. # position = p1.stimulus_on + p1.stimulus_isi ;next stimulus position
  1305. # IF (p1.stimulus_isi gt 0) then begin
  1306. # while ((position+Maxshift+1) lt (p1.frames-1)) do begin
  1307. # maskfactor(position+Maxshift-1:position+Maxshift+1)=1.0/3
  1308. # maskfactor(position-3:position-1)=-1.0/3
  1309. # position = position + p1.stimulus_isi ; move to the next stimulus
  1310. # endWhile
  1311. # endIF
  1312. # end
  1313. else:
  1314. print('ViewOverview.Overview10CTV: WARNING: wrong method in Overview10ctv, set flag[ctv_method]')
  1315. #ENDCASE
  1316. #;Now calculate the overview frame
  1317. for i in range(p1.metadata.frames): # do begin
  1318. # OverviewFrame(*,*) = OverviewFrame(*,*) + dummy(*,*,i) * maskFactor(i)
  1319. overviewFrame = overviewFrame + dummy[:,:,i]*maskFactor[i]
  1320. print('ViewOverview/overview10ctv: created frame with maskFactor, sum is :',np.sum(maskFactor))
  1321. if SPACEfilter: #dummy = smooth(dummy, Signal_FilterTimeSize)
  1322. print('ViewOverview.overview10ctv spacefilter: neg value for GAUSSIAN filter. Set filter to: ',flag.Signal_FilterSpaceSize)
  1323. # in IDL, the filter was applied to all three dimension - but a time filter should only work on time
  1324. overviewFrame = View.SpaceFilter(overviewFrame,flag.Signal_FilterSpaceSize)
  1325. #endFOR
  1326. #;apply space filter
  1327. #if (Signal_FilterSpaceSize gt 1) then OverviewFrame = SpaceFilter(OverviewFrame, Signal_FilterSpaceSize)
  1328. #ENDIF
  1329. #return, OverviewFrame
  1330. #end ; of program
  1331. return overviewFrame
  1332. def CurveToValue(curve, flag, p1):
  1333. '''
  1334. copy of CurveToValue
  1335. uses flag
  1336. translate only what is used - the rest, when needed
  1337. '''
  1338. # function curveToValue, input
  1339. #;Author Giovanni 1998
  1340. CTVmethod = flag.CTV_Method
  1341. #;externalized CTVs are:
  1342. #;values below 0 go to personal CurvetoValueLocal in ImageALLocal folder
  1343. #IF (CTVmethod lt 0) THEN result=CurveToValueLocal(curve)
  1344. if CTVmethod < 0:
  1345. print('ViewOverview.CurveToValue: values below 0 not implemented yet (local)')
  1346. #;values above 1000 go to CurveToValueMathias in ImageALMathias folder
  1347. #IF (CTVmethod gt 1000) THEN result=CurveToValueMathias(curve)
  1348. elif CTVmethod > 1000:
  1349. print('ViewOverview.CurveToValue: values above 1000 not implemented yet (Mathias)')
  1350. #;poor old Giovanni only has values between 0 and 999 (1000 is lost in ...)
  1351. #IF (CTVmethod ge 0) AND (CTVmethod le 1000) THEN begin
  1352. #CASE CTVmethod OF $
  1353. elif (CTVmethod == 1):
  1354. result = np.mean(curve[10:19]) # ;corresponds to A&S, Overview8Mean
  1355. # 2 : result = TOTAL(curve(10:19)) ;corresponds to A&S best, integral über Zeit
  1356. # 3 : begin ;gets the maximum between 10 and 19, then integral of MAX-2 to MAX+8
  1357. # s = size(curve)
  1358. # IF s(0) eq 1 THEN begin
  1359. # dummy = curve
  1360. # dummy = smooth(dummy(*),3)
  1361. # maxVal = MAX(dummy(10:19))
  1362. # index = WHERE(dummy(10:19) eq maxVal)
  1363. # result = TOTAL(curve(index(0)+8:index(0)+17)) ; ARNOs best, set frames accordingly
  1364. # endif else begin
  1365. # dummy = curve(0,0,*)
  1366. # dummy = smooth(dummy(*),3)
  1367. # maxVal = MAX(dummy(10:19))
  1368. # index = WHERE(dummy(10:19) eq maxVal)
  1369. # result = TOTAL(curve(0,0,index(0)+8:index(0)+17)) ; ARNOs best, set frames accordingly
  1370. # endelse
  1371. # end
  1372. # 4 : begin ;gets the maximum between firstFrame and lastFrame (control window), then integral of MAX-2 to MAX+8
  1373. # s = size(curve)
  1374. # if firstframe lt 2 then firstframe = 2
  1375. # IF s(0) eq 1 THEN begin
  1376. # dummy = curve
  1377. # dummy = smooth(dummy(*),3)
  1378. # maxVal = MAX(dummy(firstFrame:lastFrame))
  1379. # index = WHERE(dummy(firstFrame:lastFrame) eq maxVal)
  1380. # result = TOTAL(curve(index(0)+firstFrame-2:index(0)+firstFrame+7)) ; ARNOs best, set frames accordingly
  1381. # endif else begin
  1382. # dummy = curve(0,0,*)
  1383. # dummy = smooth(dummy(*),3)
  1384. # maxVal = MAX(dummy(firstFrame:lastFrame))
  1385. # index = WHERE(dummy(firstFrame:lastFrame) eq maxVal)
  1386. # result = TOTAL(curve(0,0,index(0)+firstFrame-2:index(0)+firstFrame+7)) ; ARNOs best, set frames accordingly
  1387. # endelse
  1388. # end
  1389. # 5 : begin ;gets the maximum between p1.stimulus_on and p1.stimulus_on+10 (control window), then integral of MAX-2 to MAX+8
  1390. # s = size(curve)
  1391. # IF s(0) eq 1 THEN begin
  1392. # dummy = curve
  1393. # dummy = smooth(dummy(*),3)
  1394. # maxVal = MAX(dummy( p1.stimulus_on: p1.stimulus_on+10))
  1395. # index = WHERE(dummy( p1.stimulus_on: p1.stimulus_on+10) eq maxVal)
  1396. # result = TOTAL(curve(index(0)+ p1.stimulus_on-2:index(0)+ p1.stimulus_on+7)) ; ARNOs best, set frames accordingly
  1397. # endif else begin
  1398. # dummy = curve(0,0,*)
  1399. # dummy = smooth(dummy(*),3)
  1400. # maxVal = MAX(dummy( p1.stimulus_on: p1.stimulus_on+10))
  1401. # index = WHERE(dummy( p1.stimulus_on: p1.stimulus_on+10) eq maxVal)
  1402. # result = TOTAL(curve(0,0,index(0)+ p1.stimulus_on-2:index(0)+ p1.stimulus_on+7)) ; ARNOs best, set frames accordingly
  1403. # endelse
  1404. # end
  1405. # 10 : result = MIN(curve(28:45))
  1406. # 11 : result = MAX(curve(10:19))
  1407. # 12 : result = TOTAL(curve(firstFrame:lastFrame)) ;total between values in control window
  1408. # 13 : result = TOTAL(curve(p1.stimulus_on+1:p1.stimulus_on+10))
  1409. # 14 : result = (TOTAL(curve(p1.stimulus_on+1:p1.stimulus_on+6)))-(TOTAL(curve(p1.stimulus_on-3:p1.stimulus_on-1)))-(TOTAL(curve(p1.stimulus_on+8:p1.stimulus_on+10)))
  1410. # ;14: contrast of 6 frames right after stimulus against 3 frames before and 3 frames after
  1411. # 15 : result = MAX(curve(firstFrame:lastFrame))
  1412. # 16 : result = MAX(curve(firstFrame:lastFrame)) - MEAN(curve(firstframe-3:firstframe))
  1413. # 17 : result = MAX(median(curve(firstFrame:lastFrame),3)) - MEAN(curve(firstframe-3:firstframe))
  1414. # 20 : result = (curve(lastframe)) - (curve(firstframe))
  1415. # 21 : result = (TOTAL(curve(p1.stimulus_on+2:p1.stimulus_on+4)) - TOTAL(curve(p1.stimulus_on-3:p1.stimulus_on-1)))/3
  1416. elif (CTVmethod == 22):
  1417. result = np.sum(curve[flag.CTV_lastframe-1:flag.CTV_lastframe+2]) - np.sum(curve[flag.CTV_firstframe-1:flag.CTV_firstframe+2])# lastframe - firstframe
  1418. # 22 : result = (TOTAL(curve(lastframe-1:lastframe+1)) - TOTAL(curve(firstframe-1:firstframe+1)))/3
  1419. elif (CTVmethod == 23):
  1420. result = np.sum(curve[p1.metadata.stimulus_on+2:round(p1.metadata.stimulus_on+3*p1.frequency)]) - np.sum(curve[round(p1.metadata.stimulus_on-3*p1.frequency):p1.metadata.stimulus_on-1])# lastframe - firstframe
  1421. # 23 : result = (TOTAL(curve(p1.stimulus_on+2:p1.stimulus_on+3*p1.frequency)) - TOTAL(curve(p1.stimulus_on-3*p1.frequency:p1.stimulus_on-1)))/(3*p1.frequency)
  1422. #;24: mean of 3 frames 1 sec after stimOnset, - mean of 3 frames before stimOnset
  1423. # 24 : result = (TOTAL(curve(p1.stimulus_on+p1.frequency-1:p1.stimulus_on+p1.frequency+1)) - TOTAL(curve(p1.stimulus_on-3:p1.stimulus_on-1)))/3
  1424. # 25 : result = TOTAL(curve(lastframe-1:lastframe+1))/3 - TOTAL(curve(firstframe-7:firstframe+1))/9;paul, Mai 2001
  1425. # 26 : result = TOTAL(curve(lastframe:lastframe+14))/15 - TOTAL(curve(firstframe:firstframe+4))/5;paul, 11.12.01
  1426. # 27 : result = TOTAL(curve(lastframe:lastframe+2))/3 - TOTAL(curve(firstframe:firstframe+4))/5;paul, 11.12.01
  1427. #
  1428. #
  1429. #
  1430. #
  1431. # 30 : result = MAX(curve(10:30))- MIN(curve(5:15)) ;
  1432. # 31 : result = MAX(curve(12:32))- MIN(curve(7:17)) ;
  1433. # 32 : result = MAX(curve(20:30))- MIN(curve(10:25)) ;
  1434. # 33 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+10))- MIN(curve(p1.stimulus_on-5:p1.stimulus_on)) ;
  1435. # ;34: max of 3 secs after stimulus - min of 2 secs before stimulus.
  1436. # 34 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+3*p1.frequency))- MIN(curve(p1.stimulus_on-2*p1.frequency:p1.stimulus_on)) ;
  1437. # ;35: max of 3 secs after stimulus - mean of 3 frames before stimulus.
  1438. # ;35 with t-test for significance, see 135/136
  1439. # 35 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+3*p1.frequency))- Mean(curve(p1.stimulus_on-2:p1.stimulus_on)) ;
  1440. elif (CTVmethod == 35):
  1441. result = np.max(curve[p1.stimulus_on:round(p1.stimulus_on+3*p1.frequency)]) - np.mean(curve[p1.stimulus_on-2:p1.stimulus_on-1])# lastframe - firstframe
  1442. # 62 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+2*p1.frequency))- Mean(curve(p1.stimulus_on-2:p1.stimulus_on)) ;
  1443. # 64 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+4*p1.frequency))- Mean(curve(p1.stimulus_on-2:p1.stimulus_on)) ;
  1444. # 66 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+6*p1.frequency))- Mean(curve(p1.stimulus_on-2:p1.stimulus_on)) ;
  1445. # 68 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+8*p1.frequency))- Mean(curve(p1.stimulus_on-2:p1.stimulus_on)) ;
  1446. #
  1447. #
  1448. # 36 : begin
  1449. # print,'Method 36 uses global maximum - use Overview Method 10 for it please or change to 35'
  1450. # result = 0
  1451. # end
  1452. # ;37: max of frames 2-5, minus mean 0-1, Daniela 2002.
  1453. # 37 : result = MAX(curve(2:5))- Mean(curve(0:1)) ;
  1454. # 38 : begin
  1455. # print,'Method 38 uses global maximum - use Overview Method 10 for it please or change to CTV=37'
  1456. # result = 0
  1457. # end
  1458. #
  1459. # 45 : begin ;gets the maximum between p1.stimulus_on and p1.stimulus_on+10 (control window), then integral of MAX-2 to MAX+8
  1460. # ;but resets curve to 0 in the interval p1.stimulus_on-2 to p1.stimulus_on-1
  1461. # s = size(curve)
  1462. # IF s(0) eq 1 THEN begin
  1463. # dummy = curve
  1464. # dummy = smooth(dummy(*),3)
  1465. # shiftZero = 5 * total(dummy[p1.stimulus_on-2:p1.stimulus_on-1])
  1466. # maxVal = MAX(dummy( p1.stimulus_on: p1.stimulus_on+10))
  1467. # index = WHERE(dummy( p1.stimulus_on: p1.stimulus_on+10) eq maxVal)
  1468. # result = TOTAL(curve(index(0)+ p1.stimulus_on-2:index(0)+ p1.stimulus_on+7)) - shiftZero
  1469. # endif else begin
  1470. # dummy = curve(0,0,*)
  1471. # dummy = smooth(dummy(*),3)
  1472. # shiftZero = 5 * total(dummy[p1.stimulus_on-2:p1.stimulus_on-1])
  1473. # maxVal = MAX(dummy( p1.stimulus_on: p1.stimulus_on+10))
  1474. # index = WHERE(dummy( p1.stimulus_on: p1.stimulus_on+10) eq maxVal)
  1475. # result = TOTAL(curve(0,0,index(0)+ p1.stimulus_on-2:index(0)+ p1.stimulus_on+7)) - shiftZero ; ARNOs best, set frames accordingly
  1476. # endelse
  1477. # end
  1478. #
  1479. # 51 : result = MAX(deriv(curve(5:20))) ;maximum of derivative
  1480. # 52 : result = MAX(deriv(curve(p1.stimulus_on:p1.stimulus_end+p1.frequency))) ;maximum of derivative
  1481. #
  1482. # ;calculation using the timing
  1483. # 61 : begin ;take the stimulus time, - the same time before stimulus
  1484. # result = (TOTAL(curve(p1.stimulus_on:p1.stimulus_end)) - TOTAL(curve(2*p1.stimulus_on-p1.stimulus_end:p1.stimulus_on-1)))$
  1485. # /(p1.stimulus_end - p1.stimulus_on)
  1486. # end
  1487. #
  1488. # 100 : result = (total(curve(4:8))/5)-(total(curve(0:2))/3)
  1489. #
  1490. # 101 : begin
  1491. # ;calculate maximum during stimulus
  1492. # ;then calculate half-maximum width after stimulus onset (Silke, 11/2001)
  1493. # noise = 4* stddev(curve((p1.stimulus_on)-7:(p1.stimulus_on)-1))
  1494. # cutoff = max(curve(p1.stimulus_on:p1.stimulus_end))
  1495. # if (cutoff gt noise) THEN begin
  1496. #
  1497. # posMax = where(curve(p1.stimulus_on:p1.stimulus_end) eq cutoff) + p1.stimulus_on
  1498. # posMax = posMax(0)
  1499. # aboveThreshold = (curve gt (0.5*cutoff))
  1500. # keep = 1
  1501. # for i=posMax,(n_elements(curve)-1) do begin
  1502. # if (aboveThreshold(i) eq 0) THEN keep = 0
  1503. # if keep THEN aboveThreshold(0) = 1 ELSE aboveThreshold(i) = 0
  1504. # endFOR
  1505. # keep = 1
  1506. # for j=0, posMax do begin
  1507. # i = posMax - j
  1508. # if (aboveThreshold(i) eq 0) THEN keep = 0
  1509. # if keep THEN aboveThreshold(0) = 1 ELSE aboveThreshold(i) = 0
  1510. # endFOR
  1511. # result = total(aboveThreshold) / p1.frequency
  1512. #
  1513. # endif ELSE begin
  1514. # result=0
  1515. # endelse
  1516. # end
  1517. #
  1518. # 103 : begin
  1519. # ;calculate time to half height of maximum
  1520. # noise = 4* stddev(curve((p1.stimulus_on)-7:(p1.stimulus_on)-1))
  1521. # cutoff = max(curve(p1.stimulus_on:p1.stimulus_end+p1.frequency*2))
  1522. # if (cutoff gt noise) THEN begin
  1523. # posHalfHeight = where(curve(p1.stimulus_on:p1.stimulus_end+p1.frequency*2) ge cutoff/2.0)
  1524. # result = posHalfHeight(0)/p1.frequency
  1525. # endif ELSE begin
  1526. # result=0
  1527. # endelse
  1528. # end
  1529. #
  1530. # ;gets the 3 seconds after stimulus, and the 3 seconds before stimulus, makes a rank-sum-test (Mann-Whitney U test)
  1531. # ;if the test is positive, returns CTV35, else 0
  1532. # ;ignore first frame
  1533. # 135 : begin
  1534. # significancelevel = 0.05
  1535. # after = curve(p1.stimulus_on:p1.stimulus_on+3*p1.frequency)
  1536. # before = curve(MAX([p1.stimulus_on-3*p1.frequency,1]):p1.stimulus_on)
  1537. # equalMean = tm_test(after,before) ; equalMean is a two element array, with z-statistic and p-value
  1538. # IF (equalMean(1) gt significancelevel) THEN begin
  1539. # result = 0
  1540. # endIF else begin
  1541. # result = MAX(after)- Mean(curve(p1.stimulus_on-2:p1.stimulus_on)) ;
  1542. # endelse
  1543. # ;print, result, equalMean
  1544. # ;plot, after
  1545. # ;oplot, before
  1546. # ;oplot, before
  1547. # end
  1548. # 136 : begin
  1549. # significancelevel = 0.01
  1550. # after = curve(p1.stimulus_on:p1.stimulus_on+3*p1.frequency)
  1551. # before = curve(MAX([p1.stimulus_on-3*p1.frequency,1]):p1.stimulus_on)
  1552. # equalMean = tm_test(after,before) ; equalMean is a two element array, with z-statistic and p-value
  1553. # IF (equalMean(1) gt significancelevel) THEN begin
  1554. # result = 0
  1555. # endIF else begin
  1556. # result = MAX(after)- Mean(curve(p1.stimulus_on-2:p1.stimulus_on)) ;
  1557. # endelse
  1558. # ;print, result, equalMean
  1559. # ;plot, after
  1560. # ;oplot, before
  1561. # ;oplot, before
  1562. # end
  1563. #
  1564. # 145 : begin ;gets the maximum between p1.stimulus_on and p1.stimulus_on+10 (control window), then integral of MAX-2 to MAX+8
  1565. # ;but resets curve to 0 in the interval p1.stimulus_on-2 to p1.stimulus_on-1
  1566. # ;only values above 0
  1567. # s = size(curve)
  1568. # IF s(0) eq 1 THEN begin
  1569. # dummy = curve
  1570. # dummy = smooth(dummy(*),3)
  1571. # shiftZero = 5 * total(dummy[p1.stimulus_on-2:p1.stimulus_on-1])
  1572. # maxVal = MAX(dummy( p1.stimulus_on: p1.stimulus_on+10))
  1573. # index = WHERE(dummy( p1.stimulus_on: p1.stimulus_on+10) eq maxVal)
  1574. # result = (TOTAL(curve(index(0)+ p1.stimulus_on-2:index(0)+ p1.stimulus_on+7)) - shiftZero)>0
  1575. # endif else begin
  1576. # dummy = curve(0,0,*)
  1577. # dummy = smooth(dummy(*),3)
  1578. # shiftZero = 5 * total(dummy[p1.stimulus_on-2:p1.stimulus_on-1])
  1579. # maxVal = MAX(dummy( p1.stimulus_on: p1.stimulus_on+10))
  1580. # index = WHERE(dummy( p1.stimulus_on: p1.stimulus_on+10) eq maxVal)
  1581. # result = (TOTAL(curve(0,0,index(0)+ p1.stimulus_on-2:index(0)+ p1.stimulus_on+7)) - shiftZero)>0
  1582. # endelse
  1583. # end
  1584. #
  1585. # 161 : result = curve(2) - 0.5 * total(curve(0:1)) ;short, Daniela, 2002
  1586. # 162 : result = curve(3) - 0.5 * total(curve(0:1))
  1587. # 163 : result = curve(4) - 0.5 * total(curve(0:1))
  1588. # 164 : result = curve(5) - 0.5 * total(curve(0:1))
  1589. # 165 : result = curve(3) - total(curve(0:2))/3.0 ;short, Ana, 2002
  1590. # 166 : result = curve(4) - total(curve(0:2))/3.0
  1591. # 167 : result = curve(5) - total(curve(0:2))/3.0
  1592. #
  1593. #
  1594. #
  1595. # ;values of 200+ for processing of raw data
  1596. # 240 : begin ;gets the maximum between p1.stimulus_on and p1.stimulus_on+10 (control window), then integral of MAX-2 to MAX+8
  1597. # ;maximum after stimulus is MAX(curve(p1.stimulus_on:p1.stimulus_on+10))
  1598. # ;minimum at stimulus is MIN(curve(p1.stimulus_on-2:p1.stimulus_on+2))
  1599. # ;total before stimulus TOTAL(curve(p1.stimulus_on-6:p1.stimulus_on))
  1600. # ;(TOTAL-MIN) is an estimate for the ongoing bleaching 3 frames long
  1601. # ;(MAX - MIN) is the deltaF
  1602. # ;deltaF/F is therefore ((TOTAL-MIN)+(MAX-MIN))/MIN, simplify, get
  1603. # result = (TOTAL(curve(p1.stimulus_on-6:p1.stimulus_on)) + MAX(curve(p1.stimulus_on:p1.stimulus_on+10))) $
  1604. # /MIN(curve(p1.stimulus_on-2:p1.stimulus_on+2))
  1605. # end
  1606. # 300: result = mean(curve) ;useful for simulated photographs
  1607. # 301: result = total(curve(5:10)) ; useful for simulated photographs, less susceptible to movement
  1608. # 302: result = mean(curve(5:10)) ; useful for simulated photographs, less susceptible to movement
  1609. # 322: result = TOTAL(curve(lastframe-1:lastframe+1)) /3
  1610. # 335 : result = MAX(curve(p1.stimulus_on:p1.stimulus_on+3*p1.frequency))
  1611. #
  1612. #
  1613. #;the family of 500 is for function fitting, e.g. stetter_curve fit
  1614. #
  1615. #
  1616. #
  1617. # 900: result = MAX(curve[p1.stimulus_on:p1.stimulus_on+10])- (TOTAL(curve[firstframe-1:firstframe+1])/3)
  1618. # 901: begin
  1619. # pos=where(curve[p1.stimulus_on:p1.stimulus_on+10] eq MAX(curve[p1.stimulus_on:p1.stimulus_on+10]))
  1620. # result = (TOTAL(curve[pos[0]+p1.stimulus_on-1:pos[0]+p1.stimulus_on+1])/3) - (TOTAL(curve[firstframe-1:firstframe+1])/3)
  1621. # end
  1622. else:
  1623. print('VieOverview.CurveToValue method not implemented yet')
  1624. return result
  1625. #end ; curvetovalue
  1626. def ShowOverviews(p1, flag):
  1627. '''
  1628. Translation of IDL program ShowOverview, which is called in the interactive view window
  1629. to show a false color coded image of the data.
  1630. All settings are taking from flag - unlike the IDL original, which was more protected.
  1631. The overview shown here is NOT the same as the one calculated in the tapestry.
  1632. for that one, call singleoverviews with localVIEW_batchmode = False.
  1633. '''
  1634. #pro ShowOverviews, signals, firstframe, lastframe, SO_MV_scalemin, SO_MV_scalemax, filter, FilterSize, experiment, p
  1635. #;this procedure displays overview pictures for all buffers
  1636. #;Author: Jasdan 1995 / Giovanni 1997, 1998
  1637. #;common globalVars
  1638. # common CFD ;Defined in CFD_Define
  1639. # common CFDConst
  1640. #; Parameters:
  1641. ### translate python flags into the local variables, i.e. the command line parameters in IDL
  1642. #; firstframe beginning and end of calculation of overview
  1643. #; lastframe
  1644. #; signals: 4 dimensional array of float with calculated signals
  1645. #; SO_MV_scalemin: minimum and maximum of y-scale
  1646. #; SO_MV_scalemax
  1647. #; filter: filter on/off
  1648. #; filtersize
  1649. #; experiment string with name of experiment
  1650. #; Parameterset
  1651. # firstframe = flag.CTV_firstframe
  1652. # lastframe = flag.CTV_lastframe
  1653. # signals = p1.sig1
  1654. SO_MV_scalemin = flag.SO_MV_scalemin
  1655. SO_MV_scalemax = flag.SO_MV_scalemax
  1656. # filter_space = 0 #
  1657. # #TODO filter_space (which was "filter" in IDL not implemented yet,
  1658. # #because I don't know the flag)
  1659. # filtersize = 0
  1660. # experiment = 'test_image'
  1661. #############end of variables in command line##
  1662. ##method = fix(flag[so_method])
  1663. # method = flag.so_Method
  1664. ##subMethod = fix( flag[ctv_method])
  1665. # subMethod = flag.CTV_Method
  1666. ##setup = fix(flag[LE_loadExp])
  1667. # setup = flag.LE_loadExp
  1668. ##individualScale = fix(flag[so_indiScale]) MOD 10 ; more complex individual scalings not included here
  1669. # individualScale = flag.SO_indiScale % 10
  1670. ##IF (fix(flag[so_indiScale]) ge 10) THEN print, 'ShowOverviews: complex individual scaling ignored, use ',individualScale
  1671. # if flag.SO_indiScale >= 10:
  1672. # print('ShowOverviews: complex individual scaling ignored, use ',individualScale)
  1673. #
  1674. # indiScale3factor = 0.2 #; set to 0.2 for 20 % border to be ignored when scaling usind idividualscale eq 3
  1675. # if individualScale > 100: # then begin
  1676. # indiScale3factor = (individualScale-100)/100.0 #; set to 0.2 for 20 % border to be ignored when scaling usind idividualscale eq 3
  1677. # individualScale = 3
  1678. ## endIF
  1679. #
  1680. maximum = SO_MV_scalemax
  1681. minimum = SO_MV_scalemin
  1682. ##################################
  1683. # here there are many options, related to
  1684. # multiple measurements (implement then when sig1 becomes 4-dimensional!
  1685. # and to add a border (not necessary in our first, easy implementation
  1686. ## and zoomfactor (since we can zoom python windows, this might not be necessary)
  1687. #############################))
  1688. # xgap = 10 # ; gaps between frames, only even numbers!
  1689. # xgap2 = xgap/2
  1690. #
  1691. #frame = fltarr(p.format_x + xgap, p.format_y)
  1692. #frame(*,*) = -1000 ; borders are black
  1693. #
  1694. #IF (p.format_x lt 100) THEN zoomfactor = 2 ELSE zoomfactor=1
  1695. #
  1696. #
  1697. #;display 'first buffer' or not?
  1698. #firstBuffer = fix(flag[LE_UseFirstBuffer])
  1699. #IF (firstBuffer lt 0) THEN begin ; guess whether to use the first buffer on the basis of the setup
  1700. # IF setup eq 0 THEN firstBuffer = 0 ; for old setup, show also air control
  1701. # IF setup eq 3 THEN firstBuffer = 1 ; for TILL, do not show AIR control
  1702. # IF setup eq 4 THEN firstBuffer = 1 ; for TILL, do not show AIR control
  1703. # IF (fix(flag[VIEW_ReportMethod]) eq 20) THEN firstBuffer = 1
  1704. # IF (fix(flag[VIEW_ReportMethod]) eq 20) THEN lastBuffer = 1
  1705. # ; if air was subtracted for correction then leave air overview away - it is 0 !
  1706. # ;this is not really appropriate when using corrected dataset - just used for backwards compatibility
  1707. # if (max(signals(*,*,0,0)) eq 0) and (min(signals(*,*,0,0)) eq 0) then firstbuffer = 1
  1708. #endIF
  1709. #
  1710. #
  1711. #
  1712. #
  1713. #min1 = fltARR(2)
  1714. #max1 = fltARR(2)
  1715. #;minimum = 10000
  1716. #;maximum = -10000
  1717. #
  1718. #if (individualScale eq 2) then begin ;scale to min/max of all frames, takes more time
  1719. # for odor = firstbuffer, p.odors do begin
  1720. # ;overviewframe = overview( signals, odor, filter, filtersize, startframe, endframe, p, method )
  1721. # overviewframe = overview( odor, method)
  1722. # min1(0) = min(overviewframe)
  1723. # max1(0) = max(overviewframe)
  1724. # minimum = min(min1)
  1725. # maximum = max(max1)
  1726. # min1(1) = minimum
  1727. # max1(1) = maximum
  1728. # endFor
  1729. #endif
  1730. #
  1731. #IF individualScale eq 0 THEN scaleString = ' ' + strcompress(string(SO_MV_scalemin)) + '/' + strcompress(string(SO_MV_scalemax)) +' '
  1732. #IF individualScale eq 1 THEN scaleString = ' i1 '
  1733. #IF individualScale eq 2 THEN scaleString = ' ' + strcompress(string(minimum)) + '/' + strcompress(string(maximum)) +' '
  1734. #IF individualScale eq 3 THEN scaleString = ' i3 '
  1735. #IF individualScale eq 4 THEN scaleString = ' i4 '
  1736. #IF individualScale eq 5 THEN scaleString = ' i5 '
  1737. #IF individualScale eq 6 THEN scaleString = ' i6 '
  1738. #IF individualScale eq 7 THEN scaleString = ' i7 '
  1739. #
  1740. #IF method eq 2 THEN borderString = ': start=' + strcompress(string(startframe+1)) + ', end=' + strcompress(string(endframe+1)) $
  1741. # ELSE borderString = ': '
  1742. #
  1743. #Fenstertitel = localOdorText(p,1) + borderString+scalestring + ', M=' + strcompress(string(method)) +'/'+strcompress(subMethod)
  1744. #
  1745. #window, /free, xsize = ( (p.format_x+xgap) * zoomfactor * (p.odors+1-firstbuffer)+xgap ), $
  1746. # ysize = p.format_y * zoomfactor, title = Fenstertitel
  1747. #
  1748. #;****
  1749. #for odor = firstbuffer, p.odors do begin
  1750. #python: create overview frame for this particular one
  1751. overviewframe = overview(p1, flag, flag.SO_Method)
  1752. # overviewframe = overview( odor, method )
  1753. # ;overviewframe = overview( signals, odor, filter, filtersize, startframe, endframe, p, method )
  1754. #
  1755. # frame(xgap2+xgap2:p.format_x+xgap2+xgap2-1, 0:p.format_y-1) = overviewframe(*,*)
  1756. #
  1757. # frame2 = rebin(frame, (p.format_x+xgap) * zoomfactor, p.format_y * zoomfactor, sample = 1)
  1758. #
  1759. # if (individualScale eq 1) then begin
  1760. # minimum = min(overviewframe)
  1761. # maximum = max(overviewframe)
  1762. #; minimum = maximum - ((maximum - minimum) / 2) ; show only top 50% of each frame
  1763. # endif
  1764. # if (individualScale eq 3) then begin
  1765. # minimum = min(overviewframe(indiScale3factor*p.format_x:p.format_x*(1-indiScale3factor),indiScale3factor*p.format_y:p.format_y*(1-indiScale3factor)))
  1766. # maximum = max(overviewframe(indiScale3factor*p.format_x:p.format_x*(1-indiScale3factor),indiScale3factor*p.format_y:p.format_y*(1-indiScale3factor)))
  1767. # endif
  1768. # if (individualScale eq 4) then begin
  1769. # ;scale with min and max of selected region
  1770. # ;restore the selected region
  1771. # restore, flag[stg_OdorMaskPath]+flag[stg_reporttag]+'.alArea'
  1772. # ;now AL perimeter is in variable maskframe
  1773. # positions = where(maskframe)
  1774. # minimum = min(overviewframe(positions))
  1775. # maximum = max(overviewframe(positions))
  1776. # endIF
  1777. plt.imshow(overviewframe, vmin=minimum, vmax=maximum)
  1778. #
  1779. # tv, bytscl(frame2, MIN=minimum, MAX=maximum, TOP=!d.table_size), (odor - firstbuffer)
  1780. #endfor
  1781. #; draw scalebar
  1782. #scalebarsize = p.format_y*zoomfactor
  1783. #scaleBar = INTARR(xgap2+1,scalebarsize)
  1784. #scale = reverse(indgen(scalebarsize))
  1785. #for i=1,xgap2 do scaleBar(i,*) = scale(*)
  1786. # IF ((minimum lt 0) and (maximum gt 0)) THEN begin ;mark 0 position
  1787. # level = fix(scalebarsize - scalebarsize*(float(minimum)/(minimum - maximum)))
  1788. # IF (level eq scalebarsize-1) THEN begin
  1789. # scaleBar(*,level-1:level)=0
  1790. # endiF ELSE begin
  1791. # scaleBar(*,level:level+1)=0
  1792. # endELSE
  1793. #endIF
  1794. #print, 'Showoverviews: indiscale is ',individualscale,' Method is ',method, ' Minimum&Maximum are: ',minimum, maximum
  1795. #
  1796. #tv, bytscl(scaleBar, MIN=0, MAX=p.format_y*zoomfactor, TOP=!d.table_size), 0
  1797. #end ; of program ShowOverviews
  1798. def Depracated_ExportMovie(flag, p1):
  1799. #gio June 2019: adapted IDL program in a temporary fashion, not elegant at all
  1800. #buffer: is what the movie should contain
  1801. buffer = p1.sig1
  1802. # original IDL file is ExportMovie.pro in VIEWoverview
  1803. # look at that file to understand what happened - I'll be deleting most of that here soon
  1804. # at the beginning I translated verbatim, then I started simplifying
  1805. # other variables in IDL were: bufferIN, Pixmin1, Pixmax1, filter, filtersize, p , FileText
  1806. # procedure to export movie frame by frame in PICT format , for Adobe Premiere for example
  1807. # adapted from a previous version by jasdan
  1808. # Giovanni 1999, 2000, 2001.
  1809. # export to AVI added, 2003
  1810. # conversion to Python May/june 2019
  1811. ## block of common variables containing flags and data
  1812. #common cfd
  1813. #common cfdconst
  1814. #common vars
  1815. #common data
  1816. ##the common block ExporMovieFlags is defined in VIEW!
  1817. #common ExportMovieFlags
  1818. mv_xgap = flag.mv_xgap # border of frame, total (i.e. half of this on each side)
  1819. mv_ygap = flag.mv_ygap
  1820. # mv_sdSignificanceCut = flag.mv_sdSignificanceCut # 0 # #NOT IMPLEMENTED#cut pixels below certain significance value, set to 0 for no significance cut
  1821. mv_exportFormat = flag.mv_exportFormat #'mpg4' # insert codec for FFM
  1822. mv_realTime = flag.mv_realTime # 24 # , NOT IMPLEMENTED $ ; insert frames per second of the movie, 0 for no realTime, 24 for MPEG, 15 for GIF->QuickTime
  1823. # mv_SpeedFactor = flag.mv_SpeedFactor # , NOT IMPLEMENTED $ ; for exportFormat 6, increase or decrease speed of movie
  1824. mv_reverseIt = flag.mv_reverseIt # False #, $; turn it upside down
  1825. mv_rotateImage = flag.mv_rotateImage #0 #, $ ; rotate only image, ; 0 for no action, 2 for 180 degrees
  1826. mv_cutborder = flag.mv_cutborder# 1 #, $ ; die Pixelgröße von Filtersize wird ringsherum vom Bild abgeschnitten
  1827. mv_morphoThreshold = flag.mv_morphoThreshold # False #, $;;1; substitutes lower range with morphological image to be taken from file
  1828. mv_withinMask = flag.mv_withinMask # False #,#NOT IMPLEMENTED# $; = 0 ; limits output to within the mask in xxx.area
  1829. # mv_sdSignificanceCut = 0 #, $;2.0 ; cuts everything below that significance level. Stimulus is included in calculation, ignored if below 0.1. Not implemented yet
  1830. mv_markStimulus = flag.mv_markStimulus # True #, $ ; marks stimulus application with a red box
  1831. mv_percentileScale = flag.mv_percentileScale # False #, $; = 0 !!!!!!discontinued
  1832. mv_indiScale3factor = flag.mv_indiScale3factor # 0.2 # set to 0.2 for 20 % border to be ignored when scaling usind idividualscale eq 3
  1833. mv_individualScale = flag.mv_individualScale # 3 # 3 and 4 implemented;, $; = fix(flag[so_indiScale])
  1834. #mv_individualScale = fix(flag[so_indiScale])
  1835. #IF ((mv_individualScale gt 100) AND (mv_individualScale lt 200)) then begin
  1836. # mv_indiScale3factor = (mv_individualScale-100)/100.0 ; set to 0.2 for 20 % border to be ignored when scaling usind idividualscale eq 3
  1837. # mv_individualScale = 3
  1838. #endIF
  1839. mv_percentileValue = flag.mv_percentileValue # 0#NOT IMPLEMENTED# , $; = float(individualScale MOD 100)/100.0
  1840. mv_correctStimulusOnset = flag.mv_correctStimulusOnset # 0 #value to be added to stimulus onset
  1841. mv_displayTime = flag.mv_displayTime # False # #NOT IMPLEMENTED#time in ss:ms as figures
  1842. mv_minimumBrightness = flag.mv_minimumBrightness # 0 ##NOT IMPLEMENTED# 0.4 #; creates a mask that depends on the brightnes of the foto
  1843. #;0, 1: Pixmin and Pixmax are taken
  1844. #;2 : min and maximum of sequence is taken
  1845. #;3 : min and max of central region is taken
  1846. #;4 : max of sequence is taken, min is Pixmin
  1847. #;5 : min and max from area region
  1848. #;6 : min from pixmin, max from area
  1849. #;7 : min from pixmin, max from area but only stimulus + 2*stimulus length
  1850. #
  1851. #IF ((mv_individualScale gt 1000) AND (mv_individualScale lt 2000)) then begin
  1852. # mv_percentileValue = float(mv_individualScale MOD 100)/100.0
  1853. # mv_percentileScale = 1
  1854. # mv_individualScale = (mv_individualScale MOD 1000) / 100 ; 1xyy, x gives individualscale
  1855. # mv_indiScale3factor = 0.2 ; set to 0.2 for 20 % border to be ignored when scaling usind idividualscale eq 3
  1856. #endIF
  1857. ##all settings for export movie are now in the file
  1858. ##SetExportMovieFlags in the ImageALLocal path
  1859. ##call stored values only in interactive mode
  1860. #IF (flag[BatchMode] eq 0) THEN SetExportMovieFlags
  1861. # I assume the data was read by something like FID_in.read_pst
  1862. # format is (rows, columns, frames)
  1863. #local flags: I collect everything here, and repeat everything later for the translation
  1864. # later the program can be made tidy
  1865. suppressMilliseconds = 0 #if 1 does not show milliseconds, but always shows minutes (for slow measurements)
  1866. # variables in p1
  1867. # TODO replace these temporary values with the real ones.
  1868. print('In ViewOverview-ExportMovie: mv_individualScale not implemented yet, taking min/max of movie')
  1869. scaleMin = np.min(buffer)
  1870. scaleMax = np.max(buffer)
  1871. filterSpaceFlag = flag.Signal_FilterSpaceFlag
  1872. filterSpaceSize = flag.Signal_FilterSpaceSize
  1873. # in python, I use gaussian filter, therefore filterSpaceSize is sigma, not number of pixels as in my IDL code
  1874. # which file to write the movie to:
  1875. # the filename is given in imageALlocal/localodortext
  1876. if flag.VIEW_batchmode:
  1877. filetext = ImageALlocal.localodortext(flag, p1)
  1878. else:
  1879. filetext = 'movie' #in interactive mode movies do not have an informative name
  1880. # not add the right directory
  1881. outfilename = os.path.join(flag.STG_OdorReportPath, filetext)
  1882. outfilename = outfilename + '.mp4'
  1883. p1_stimulus_on = p1.stimulus_on
  1884. p1_stimulus_end = p1.stimulus_end
  1885. p1_format_x = buffer.shape[0]
  1886. p1_format_y = buffer.shape[1]
  1887. p1_stimulus_ISI = p1.stimulus_ISI
  1888. p1_frequency = p1.frequency # frames per second
  1889. p1_frame_time = 1000.0/p1_frequency
  1890. #flags are defined in View/View.pro
  1891. #which part to show is defined by flags
  1892. #MvFirstframe = fix(flag[ft_firstframe])
  1893. #MvLastframe = fix(flag[ft_lastframe])
  1894. #IF (MvFirstFrame eq -1) THEN MvFirstFrame = 0
  1895. #IF (MvLastFrame eq -1) THEN MvLastFrame = p1_frames-1
  1896. #if (Mvlastframe gt p1_frames-1)then Mvlastframe = p1_frames-1
  1897. mv_FirstFrame = 0 #starting with first frame
  1898. mv_LastFrame = buffer.shape[2]-1 # up to last frame
  1899. print('Exportmovie. Exporting frames ',mv_FirstFrame,' to ', mv_LastFrame,' of the original data')
  1900. mv_drawScalebar = False
  1901. foto1 = buffer[:,:,0] # take first frame as back foto
  1902. ##get name for movie
  1903. #IF fix(flag[VIEW_batchmode]) THEN begin
  1904. # fileText = localOdorText(p1, odor)
  1905. #endIF else begin
  1906. fileText = 'movie'
  1907. #endELSE
  1908. #IF (VIEW_CorrSignals eq 0) THEN begin
  1909. # buffer = sig1(*,*,Mvfirstframe:Mvlastframe,odor)
  1910. # fileText = filetext
  1911. #endIF ELSE begin
  1912. # buffer = sig1corr(*,*,Mvfirstframe:Mvlastframe,odor)
  1913. # fileText = filetext + 'corr'
  1914. #endELSE
  1915. pixMIN = scaleMin
  1916. pixMAX = scaleMax
  1917. filterFlag = filterSpaceFlag
  1918. filterSize = filterSpaceSize
  1919. temp = np.zeros((p1_format_x , p1_format_y ))
  1920. #frame = fltarr(p1_format_x + xgap, p1_format_y + ygap)
  1921. frame_Xsize = p1_format_x + mv_xgap + ((p1_format_x + mv_xgap) % 2)
  1922. frame_Ysize = p1_format_y + mv_ygap + ((p1_format_y + mv_ygap) % 2)
  1923. frame = np.zeros((frame_Xsize, frame_Ysize)) #no odd numbers for mpeg
  1924. #triple frame for mpeg
  1925. #triFrame = bytarr(3,p1_format_x +mv_xgap+(p1_format_x MOD 2), p1_format_y +mv_ygap+(p1_format_y MOD 2))
  1926. #get color information for tiff output
  1927. #IF fix(flag[macSystem]) THEN device, true_color = 0
  1928. #device, decomposed=0
  1929. #loadct, SO_MV_colortable
  1930. #TVLCT, R, G, B, /GET
  1931. #make values 0 and 1 black for background
  1932. #r(0) = 0
  1933. #g(0) = 0
  1934. #b(0) = 0
  1935. #set these colours also to the screen
  1936. #tvlct, r, g, b
  1937. #IF (mv_exportformat eq 3) THEN begin
  1938. # outfilename = flag[stg_odorreportpath] + FileText +'.mpeg'
  1939. # myMPEG = OBJ_NEW('IDLgrMPEG', FILENAME=outfilename, scale=[2.0,2.0], FRAME_RATE=2)
  1940. #endIF
  1941. #IF (mv_exportformat eq 4) THEN outfilename = flag[stg_odorreportpath] + FileText +'.gif'
  1942. #IF (mv_exportformat eq 5) THEN outfilename = flag[stg_odorreportpath] + FileText +'.tif'
  1943. #IF (mv_exportformat eq 6) THEN outfilename = flag[stg_odorreportpath] + FileText +'.avi'
  1944. xgap2 = int(mv_xgap/2)
  1945. ygap2 = int(mv_ygap/2)
  1946. noFrames = mv_LastFrame - mv_FirstFrame +1 #number of frames
  1947. stimStart = p1_stimulus_on - mv_FirstFrame + mv_correctStimulusOnset
  1948. stimEnd = p1_stimulus_end - mv_FirstFrame + mv_correctStimulusOnset
  1949. #make array of stimulus information, for repeated stimulation, values of 1 for frames with stimulus
  1950. stimArray = np.full((noFrames), False)
  1951. #mark first stimulus
  1952. stimArray[stimStart:stimEnd] = True
  1953. #if it crashes here, maybe the stimulus is not part of the movie - remove label stimulus option
  1954. #mark successive stimuli
  1955. NextEnd = stimEnd + p1_stimulus_ISI
  1956. NextStart = stimStart + p1_stimulus_ISI
  1957. if (p1_stimulus_ISI > 0):
  1958. while (NextEnd < noFrames-1):
  1959. stimArray[NextStart:NextEnd] = True
  1960. NextEnd = NextEnd + p1_stimulus_ISI
  1961. NextStart = NextStart + p1_stimulus_ISI
  1962. #recalculate time base
  1963. filmFrequency = p1_frequency
  1964. if (mv_realTime > 1):
  1965. filmFrequency = mv_realTime
  1966. time = (noFrames) / p1_frequency # seconds of film duration
  1967. print('Calculated frame length in ExportMovie: ',time*1000/(noFrames),'. Reported frame length: ',p1_frame_time,'. Check consistency!')
  1968. oldFrames = noFrames
  1969. noFrames = int(time * mv_realTime)
  1970. # # the following resamples using fft along the time axis
  1971. # from scipy.signal import resample
  1972. # buffer1 = resample(buffer, noFrames, t=None, axis=2, window=None)
  1973. buffer = sci.zoom(buffer, (1,1,noFrames/oldFrames), mode='nearest')
  1974. #also for stimulus
  1975. stimArray = sci.zoom(stimArray, noFrames/oldFrames, mode='nearest')
  1976. stimStart = int(stimStart * noFrames/oldFrames)
  1977. stimEnd = int(stimEnd * noFrames/oldFrames)
  1978. print('Saving ',noFrames,' frames for ',time,' seconds of film. Stimulus is between frames ',stimStart, stimEnd)
  1979. if mv_displayTime:
  1980. timeArray = np.arange(noFrames) # findgen(noFrames)
  1981. timeArray = timeArray / filmFrequency
  1982. timeArray = timeArray - timeArray[stimStart]
  1983. ##define window size. Must be even for MPEG
  1984. #window, 10, xsize=p1_format_x +mv_xgap+(p1_format_x MOD 2), ysize=p1_format_y +mv_ygap+(p1_format_y MOD 2)
  1985. #go through frames to filter
  1986. if filterSpaceFlag:
  1987. for i in np.arange(noFrames-1):
  1988. buffer[:,:,i] = sci.gaussian_filter(buffer[:,:,i], filterSpaceSize)
  1989. #IDL: buffer(*,*,i) = smooth( buffer(*,*,i), filterSpaceSize, /edge)
  1990. # #get the limit values for the false color assignment
  1991. # if (mv_individualScale == 2): #scale to min/max of all frames
  1992. # if mv_percentileScale:
  1993. # pixMIN = percentile(buffer, mv_percentileValue)
  1994. # pixMAX = percentile(buffer, 1-mv_percentileValue)
  1995. # else:
  1996. # pixMin = MIN(buffer)
  1997. # pixMAX = MAX(buffer)
  1998. if (mv_individualScale == 3): #scale to min/max of all frames, central region only
  1999. pixMIN = np.min(buffer[int(p1_format_x *mv_indiScale3factor):int(p1_format_x *(1-mv_indiScale3factor)),int(p1_format_y *mv_indiScale3factor):int(p1_format_y *(1-mv_indiScale3factor)),:])
  2000. pixMAX = np.max(buffer[int(p1_format_x *mv_indiScale3factor):int(p1_format_x *(1-mv_indiScale3factor)),int(p1_format_y *mv_indiScale3factor):int(p1_format_y *(1-mv_indiScale3factor)),:])
  2001. if (mv_individualScale == 4): #scale to max of all frames
  2002. pixMAX = np.max(buffer)
  2003. #if ((mv_individualScale ge 5)and(mv_individualScale le 7)) then begin
  2004. # #scale with min and max of selected region
  2005. # #restore the selected region
  2006. # #5: min max in region
  2007. # #6: min fixed, max in region
  2008. # #7: min fixed, max in region during and immediately after stimulus
  2009. # restore, flag[stg_OdorMaskPath]+flag[stg_reporttag]+'.Area'
  2010. # #correct for unequal size array
  2011. # dummy = bytarr(p1_format_x ,p1_format_y ) # get same size array
  2012. # dummy(*)=0
  2013. # xtop = min([(size(maskframe))(1),(size(dummy))(1)] ) -1
  2014. # ytop = min([(size(maskframe))(2),(size(dummy))(2)] ) -1
  2015. # dummy(0:xtop,0:ytop) = maskframe(0:xtop,0:ytop)
  2016. # #shift maskframe
  2017. # maskframe = shift(maskframe, p1_shiftX, p1_shiftY)
  2018. # #now AL perimeter is in variable maskframe
  2019. # #create 3D mask
  2020. # dummy = buffer
  2021. # dummy(*) = 0
  2022. # IF (mv_individualscale eq 7) THEN begin
  2023. # #consider time during stimulus
  2024. # #and again the length of the stimulus
  2025. # #i.e. with 1 sec stimulus, consider 3 secs after stimulus onset
  2026. # length = 2 * (stimend - stimstart)
  2027. # countdown = 0
  2028. # for i=0,noFrames-1 do begin
  2029. # IF stimarray(i) THEN begin
  2030. # dummy(*,*,i)=maskframe(*,*)
  2031. # countDown = length
  2032. # endIF
  2033. # IF countDown gt 0 THEN dummy(*,*,i)=maskframe(*,*)
  2034. # countDown = countDown - 1
  2035. # endFOR
  2036. # endIF else begin
  2037. # for i=0, noFrames-1 do dummy(*,*,i)=maskframe(*,*)
  2038. # endELSE
  2039. # positions = where(dummy)
  2040. # IF mv_percentileScale THEN begin
  2041. # if (mv_individualScale eq 5) then pixmin = percentile(buffer(positions),mv_percentileValue)
  2042. # pixmax = percentile(buffer(positions),1-mv_percentileValue)
  2043. # endIF else begin
  2044. # if (mv_individualScale eq 5) then pixmin = min(buffer(positions))
  2045. # pixmax = max(buffer(positions))
  2046. # endELSE
  2047. # #save space, free memory
  2048. # dummy = 0
  2049. # positions = 0
  2050. #endIF #indiscale 5
  2051. #get colors for border and stimulus bar
  2052. #Pixmax = float(pixMax)
  2053. #pixMin = float(pixMin) #don't ask me why IDL interprets these as integers sometime
  2054. #buffer = temporary(buffer) > PixMin
  2055. #buffer = temporary(buffer) < PixMax
  2056. buffer = np.clip(buffer, pixMIN, pixMAX)
  2057. valueRange = pixMAX - pixMIN
  2058. valueStep = valueRange/255
  2059. redcolor = pixMAX - valueRange/253 #
  2060. print('Exportmovie: MAX: ', pixMAX, ' MIN: ', pixMIN)
  2061. #shift max and min so that values 0 and 255 can be set to black and white
  2062. pixMAX = pixMAX + valueStep*2
  2063. pixMIN = pixMIN - valueStep*2
  2064. #
  2065. ##take only pixels that in the photo have reached threshold
  2066. # if (mv_minimumBrightness > 0):
  2067. # #get Photo
  2068. ## if RM_differentViews:
  2069. ## fotoFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+p1_viewLabel+'.morpho.tif'
  2070. ## else:
  2071. ## fotoFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+'.morpho.tif'
  2072. ## if existfile(fotoFileName):
  2073. ## backfoto = read_tiff(fotoFileName)
  2074. ## else:
  2075. ## backfoto=foto1
  2076. #
  2077. # backfoto = foto1
  2078. #
  2079. #
  2080. #
  2081. # #get positions that match criterium
  2082. # criterium = mv_minimumBrightness*MAX(backfoto)
  2083. # Maskpositions = where(backfoto lt criterium) #take outside
  2084. #
  2085. #
  2086. ##morphoThreshold load foto
  2087. #IF mv_morphoThreshold then begin
  2088. # IF fix(flag[RM_differentViews]) THEN begin
  2089. # fotoFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+p1_viewLabel+'.morpho.tif'
  2090. # endIF else begin
  2091. # fotoFileName = flag[stg_OdorMaskPath]+flag[stg_ReportTag]+'.morpho.tif'
  2092. # endELSE
  2093. # IF existfile(fotoFileName) THEN backfoto = read_tiff(fotoFileName) ELSE backfoto=foto1
  2094. # backfoto = bytscl(backFoto)/2 #take only positions 0 to 127
  2095. # #redifine color table
  2096. # line=bindgen(128)
  2097. # r(0:127)=line(*)*2+1
  2098. # g(0:127)=line(*)*2+1
  2099. # b(0:127)=line(*)*2+1
  2100. # tvlct, r, g, b
  2101. #endIF
  2102. #
  2103. ##within mask: load perimeter
  2104. # IF mv_withinMask THEN begin
  2105. # #get mask into maskframe
  2106. # restore, flag[stg_OdorMaskPath]+flag[stg_reporttag]+'.Area'
  2107. # #correct for unequal size array
  2108. # dummy = bytarr(p1_format_x ,p1_format_y ) # get same size array
  2109. # xtop = min([(size(maskframe))(1),(size(dummy))(1)] ) -1
  2110. # ytop = min([(size(maskframe))(2),(size(dummy))(2)] ) -1
  2111. # dummy(0:xtop,0:ytop) = maskframe(0:xtop,0:ytop)
  2112. # #shift maskframe
  2113. # maskframe = shift(maskframe, p1_shiftX, p1_shiftY)
  2114. # #now AL perimeter is in variable maskframe
  2115. # Maskpositions = where(maskframe eq 0) #take outside
  2116. # endIF
  2117. ##############################################
  2118. # from now on, I depart from IDL in this python translation
  2119. # but, for the time being, I remain in the frame-by-frame architecture
  2120. # but, frames are RGB and not bytes
  2121. #save_movie_file_xyt in FID_out is this:
  2122. #def save_movie_file_xyt(dataMtrx, lcl_flags='', fps=24, bitrate="256k", movie_filename=''):
  2123. # so all I need is a dataMtrx, float is ok
  2124. #define 3D structure
  2125. MovieArray3D = np.zeros((frame_Xsize, frame_Ysize, noFrames))
  2126. #now go through the individal frames of the film
  2127. #***********************************************
  2128. for i in np.arange(noFrames):
  2129. #delete frame, set to black
  2130. frame = np.full((frame_Xsize, frame_Ysize), pixMIN, dtype=float) # borders are black
  2131. #mv_cutborder now is the numbers of pixels to cut
  2132. #copy image into frame
  2133. if (mv_cutborder > 0):
  2134. frame[xgap2+mv_cutborder:p1_format_x+xgap2-mv_cutborder, ygap2+mv_cutborder:p1_format_y +ygap2-mv_cutborder] = buffer[mv_cutborder:p1_format_x -mv_cutborder, mv_cutborder:p1_format_y -mv_cutborder,i]
  2135. else:
  2136. frame[xgap2:p1_format_x +xgap2, ygap2:p1_format_y +ygap2] = buffer[:,:,i]
  2137. #f = bytscl(frame, min = Pixmin, max = Pixmax, top = !d.table_size)
  2138. # #add background photo
  2139. # IF mv_morphoThreshold then begin
  2140. # dummy = f(xgap2:p1_format_x +xgap2-1,ygap2:p1_format_y +ygap2-1)
  2141. # index = where(dummy lt 128)
  2142. # dummy(index) = backFoto(index)
  2143. # f(xgap2:p1_format_x +xgap2-1,ygap2:p1_format_y +ygap2-1) = dummy(*,*)
  2144. # endIF
  2145. # #remove everything outside the mask
  2146. # IF (mv_withinMask OR (mv_minimumBrightness gt 0)) THEN begin
  2147. # dummy = f(xgap2:p1_format_x +xgap2-1,ygap2:p1_format_y +ygap2-1) # get same size array
  2148. # IF mv_morphoThreshold THEN begin
  2149. # dummy(Maskpositions) = backFoto(Maskpositions)
  2150. # endIF else begin
  2151. # dummy(Maskpositions) = 0
  2152. # endELSE
  2153. # f(xgap2:p1_format_x +xgap2-1,ygap2:p1_format_y +ygap2-1) = dummy(*,*)
  2154. # endIF
  2155. #so far, its just the image without stimulus mark and time, rotate if necessary
  2156. #rotateImage = 2
  2157. #f = rotate(f,mv_rotateImage) # 0 for no action, 2 for 180 degrees
  2158. #mark stimulus time
  2159. if mv_markStimulus:
  2160. border = int(mv_xgap/10)
  2161. if stimArray[i]:
  2162. #frame(0:p1_format_x +xgap-1, p1_format_y gap2-xgy+ygap2+3:p1_format_y +ygap-1) = redcolor # duftbalken rot
  2163. #frame(border:xgap2-border, (p1_format_y +ygap2-1)-(xgap2-2*border):p1_format_y +ygap2-1) = redcolor # duftQuadrat rot
  2164. frame[border:xgap2-border, ygap2:ygap2+xgap2-border-border+2] = pixMAX + valueStep # duftQuadrat rot
  2165. #mark time
  2166. # IF (mv_displayTime) then begin #
  2167. # IF (ygap2 lt 5) THEN begin
  2168. # print, '**************************** no space to display time, please increase ygap'
  2169. # endIF else begin
  2170. # IF i gt 0 then begin #don't display time on the first frame
  2171. # #timevalue for this frame
  2172. # timeValue = timeArray(i)
  2173. # lessThanZero = 0
  2174. # IF (timeValue lt 0) then begin
  2175. # lessThanZero = 1
  2176. # timeValue = timeValue * (-1)
  2177. # endIF
  2178. # numSeconds = floor(timevalue)
  2179. # numMinutes = fix(numSeconds / 60)
  2180. # numSeconds = numSeconds MOD 60 # seconds
  2181. # stringSeconds = stringZero(2,numSeconds)
  2182. # stringMinutes = stringZero(2,numMinutes)
  2183. # stringMilliSeconds = stringZero(2,floor((timevalue-floor(timevalue))*100) )
  2184. # IF (numMinutes ge 1) THEN begin
  2185. # timeString = stringMinutes + ':'+ stringSeconds + ':' + stringMilliSeconds
  2186. # endIF else begin
  2187. # timeString = stringSeconds + ':' + stringMilliSeconds
  2188. # endElse
  2189. # #for slow movies, no milliseconds but always minutes
  2190. # IF suppressMilliseconds THEN timeString = stringMinutes + ':'+ stringSeconds
  2191. # #now output this string to the frame
  2192. # #IF necessary because '-' is wider than ' '
  2193. # IF lessThanZero THEN begin
  2194. # Text2Array, 1, p1_format_x , 1, ygap2-1, '-'+timeString, f
  2195. # endIF else begin
  2196. # Text2Array, 5, p1_format_x , 1, ygap2-1, ' '+timeString, f
  2197. # endElse
  2198. # endIF#not first frame
  2199. # endELSE# ygap
  2200. # endIF#displaytime
  2201. if mv_reverseIt:
  2202. frame = frame[:,::-1] # reverse(f,2) # turn it upside down
  2203. #IF (NOT fix(flag[batchMode])) THEN tv, f
  2204. MovieArray3D[:,:,i] = frame
  2205. print('Saving file.... ', outfilename)
  2206. # now use ffmpeg routine
  2207. save_movie_file_xyt(MovieArray3D, fps=24, bitrate="256k", movie_filename=outfilename)
  2208. def ExportMovie(flag, p1):
  2209. # gio June 2019: adapted IDL program in a temporary fashion, not elegant at all
  2210. # original IDL file is ExportMovie.pro in VIEWoverview
  2211. # streamlined version with less IDL clutter
  2212. # refer to Deprecated_ExportMovie for a cluttered version that would explain the history
  2213. # filename to write to
  2214. # the filename is given in imageALlocal/localodortext
  2215. if flag.VIEW_batchmode:
  2216. filetext = ImageALlocal.localodortext(flag, p1)
  2217. else:
  2218. filetext = 'movie' #in interactive mode movies do not have an informative name
  2219. # now add the right directory
  2220. outfilename = os.path.join(flag.STG_OdorReportPath, filetext)
  2221. outfilename = outfilename + '.mp4'
  2222. #Aug 2019: we have removed flag.FT_FirstFrame, replaced by flag.mv_FirstFrame
  2223. #so, new yml files will not have FT_FirstFrame, and we have to check for it
  2224. if "FT_FirstFrame" not in flag:
  2225. flag.FT_FirstFrame = flag.mv_FirstFrame
  2226. if "FT_LastFrame" not in flag:
  2227. flag.FT_LastFrame = flag.mv_LastFrame
  2228. # select movie range
  2229. # TODO implement the possibility of a subselection of frames
  2230. # needs new flag values mv_firstframe and mv_lastframe
  2231. # defined ad hoc here
  2232. mv_FirstFrame = np.min((flag.FT_FirstFrame, p1.metadata.frames)) #avoid first frames after last movie frame
  2233. if flag.FT_FirstFrame == -1:
  2234. mv_FirstFrame = 0 #starting with first frame
  2235. mv_LastFrame = np.max((flag.FT_LastFrame, 0)) #avoid negative last frames
  2236. if flag.FT_LastFrame == -1:
  2237. mv_LastFrame = p1.metadata.frames #ending with last frame
  2238. print('Exportmovie. Exporting frames ',mv_FirstFrame,' to ', mv_LastFrame,' of the original data')
  2239. noFrames = mv_LastFrame-mv_FirstFrame #number of frames
  2240. # select 3D array x,y,z for movie
  2241. #TODO include cutborder here
  2242. buffer_center = p1.sig1.copy()[:,:,mv_FirstFrame:mv_FirstFrame+noFrames]
  2243. #TODO flag.mv_realtime
  2244. # this is necessary if display time changes
  2245. # may need recalculation of frames
  2246. # and as a consequence also of time axis (values)
  2247. # and of stimulus array
  2248. #apply filter
  2249. if flag.Signal_FilterSpaceFlag:
  2250. for i in np.arange(noFrames-1):
  2251. buffer_center[:,:,i] = sci.gaussian_filter(buffer_center[:,:,i], flag.Signal_FilterSpaceSize)
  2252. #TODO apply time filter
  2253. # SCALING
  2254. #if flag.mv_individualScale == 0:
  2255. #manually set scale - default
  2256. PIXmin = flag.SO_MV_scalemin
  2257. PIXmax = flag.SO_MV_scalemax
  2258. if flag.mv_individualScale == 2:
  2259. #min/max of entire movie (only the frames to be displayed)
  2260. PIXmin = np.min(p1.sig1[:,:,mv_FirstFrame:mv_FirstFrame+noFrames])
  2261. PIXmax = np.max(p1.sig1[:,:,mv_FirstFrame:mv_FirstFrame+noFrames])
  2262. if flag.mv_individualScale == 3:
  2263. #min/max of central area of movie (only the frames to be displayed). 'center' defined by mv_indiScale3factor
  2264. xborder = int(p1.metadata.format_x * flag.mv_indiScale3factor)
  2265. yborder = int(p1.metadata.format_y * flag.mv_indiScale3factor)
  2266. PIXmin = np.min(p1.sig1[xborder:-xborder, yborder:-yborder, mv_FirstFrame:mv_FirstFrame+noFrames])
  2267. PIXmax = np.max(p1.sig1[xborder:-xborder, yborder:-yborder, mv_FirstFrame:mv_FirstFrame+noFrames])
  2268. #TODO implement other scaling options, in particular within .area file
  2269. # apply scaling, creating new buffer
  2270. buffer_center = np.clip(buffer_center, PIXmin, PIXmax)
  2271. # in a 8 bit world, I need a value one step below, and one step above, for labels/borders/writings etc.
  2272. # if python does not 8bit mapping, this needs to be changed
  2273. bottomValue = PIXmin - (PIXmax-PIXmin)/256
  2274. topValue = PIXmax + (PIXmax-PIXmin)/256
  2275. # create movie array
  2276. # size of x/y, plus the border defined by mv_xgap and mv_ygap
  2277. frame_Xsize = p1.metadata.format_x + flag.mv_xgap + ((p1.metadata.format_x + flag.mv_xgap) % 2)
  2278. frame_Ysize = p1.metadata.format_y + flag.mv_ygap + ((p1.metadata.format_y + flag.mv_ygap) % 2)
  2279. # the border is filled woth bottomValue in order to have a black border (with the appropriate color scale)
  2280. buffer = np.full((frame_Xsize, frame_Ysize, noFrames),bottomValue) #no odd numbers for mpeg
  2281. # dependent variables
  2282. xgap2 = int(flag.mv_xgap/2) #border is half size on each side
  2283. ygap2 = int(flag.mv_ygap/2)
  2284. #buffer: is what the data for the movie, format x,y,t
  2285. buffer[xgap2:xgap2+p1.metadata.format_x, ygap2:ygap2+p1.metadata.format_y, :] = buffer_center
  2286. del(buffer_center) #free memory space
  2287. # buffer now contains the movie WITH border,
  2288. # so now comes the part that uses the border, such as adding time and stimulus
  2289. ### Mark stimulus frames
  2290. #make array of stimulus information, True for time points with stimulus
  2291. stimArray = np.full((noFrames), False)
  2292. # second stimulus, if present
  2293. stimStart = p1.stim2ON - mv_FirstFrame + flag.mv_correctStimulusOnset
  2294. stimEnd = p1.stim2OFF - mv_FirstFrame + flag.mv_correctStimulusOnset
  2295. stimArray[stimStart:stimEnd] = True
  2296. # mark first stimulus. I treat this second, because it is the reference for stimulus_ISI below
  2297. stimStart = p1.stimulus_on - mv_FirstFrame + flag.mv_correctStimulusOnset
  2298. stimEnd = p1.stimulus_end - mv_FirstFrame + flag.mv_correctStimulusOnset
  2299. stimArray[stimStart:stimEnd] = True
  2300. #if it crashes here, maybe the stimulus is not part of the movie - remove label stimulus option
  2301. #mark successive stimuli, for repeated stimuli
  2302. if (p1.stimulus_ISI > 0): # repetitive stimuli. Limited number not implemented yet
  2303. NextStart = stimStart + p1.stimulus_ISI
  2304. NextEnd = stimEnd + p1.stimulus_ISI
  2305. while (NextEnd < noFrames-1):
  2306. stimArray[NextStart:NextEnd] = True
  2307. NextStart = NextStart + p1.stimulus_ISI
  2308. NextEnd = NextEnd + p1.stimulus_ISI
  2309. # now stimArray contains all frames with stimulus
  2310. if flag.mv_markStimulus:
  2311. border = int(flag.mv_xgap/10)
  2312. for i in np.arange(noFrames-1):
  2313. if stimArray[i]:
  2314. buffer[border:xgap2-border, ygap2:(2 * ygap2 - 2 * border), i] = topValue
  2315. #TODO display time values (minutes:seconds:milliseconds)
  2316. # with the option to drop minutes, or to drop milliseconds
  2317. # I had a local flag 'suppressmilliseconds'
  2318. if flag.mv_displayTime: #calculate array for time values
  2319. timeArray = np.arange(noFrames) # findgen(noFrames)
  2320. timeArray = timeArray / p1.frequency
  2321. timeArray = timeArray - timeArray[stimStart]
  2322. # time is always 0 at the start of the first stimulus
  2323. # for i in np.arange(noFrames-1):
  2324. #draw time letters into frame
  2325. print('Saving file.... ', outfilename)
  2326. # now use ffmpeg routine
  2327. save_movie_file_xyt(buffer, fps=24, bitrate="1024k", movie_filename=outfilename)