source: sans/SANSReduction/branches/kline_29MAR07/Put in User Procedures/SANS_Reduction_v5.00/RealTimeUpdate_RT.ipf @ 82

Last change on this file since 82 was 41, checked in by srkline, 16 years ago

change to UNIX line endings

File size: 17.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=4.0
4
5//*****************************
6// Vers. 1.0 100401
7//
8// hook function and associated procedures that interact with the user
9// and the RealTime_SANS window
10// -displays pixel counts
11// - displays Q, qx, qy values
12// - displays q axes and pixel axes
13//
14// - of course, displays the detector image, w/ nice colors, legend, sliders to adjust color mapping
15// and a control bar to let the user adjust scaling, do averaging...
16//
17// as of 110101, the help file has not been written
18//
19//*****************************
20
21// takes care of all of the necessary initialization for the RT control process
22// creates the folders, etc. that are needed for the SANS reduction package as well, but the end user
23// doesn't need to see this.
24//
25// only used for testing - as this will re-initialize everything, including globals used as preferences
26//
27Proc Init_for_RealTime()
28        // initialize the reduction folders as for normal SANS Reduction, but don't draw the main Reduction control panel
29        InitFolders()
30        InitFakeProtocols()
31        InitGlobals()
32       
33        // specific for RealTime display
34        //set the current display type to RealTime
35        String/G root:myGlobals:gDataDisplayType = "RealTime"
36        // draw the RealTime control panel
37        Show_RealTime_Panel()
38End
39
40// Proc to bring the RT control panel to the front, always initializes the panel
41// - always initialize to make sure that the background task is properly set
42//
43Proc Show_RealTime_Panel()
44        Init_RT()               //always init, data folders and globals are created here
45        DoWindow/F RT_Panel
46        if(V_flag==0)
47                RT_Panel()
48        Endif
49End
50
51// folder and globals that are needed ONLY for the RT process
52//
53Function Init_RT()
54        //create folders
55        NewDataFolder/O root:RealTime
56        NewDataFolder/O/S root:myGlobals:RT
57        //create default globals only if they don't already exist, so you don't overwrite user-entered values.
58        NVAR xCtr=xCtr
59        if(NVAR_Exists(xctr)==0)
60                Variable/G xCtr=110                     //pixels
61        endif
62        NVAR yCtr=yCtr
63        if(NVAR_Exists(yCtr)==0)
64                Variable/G yCtr=64
65        endif
66        NVAR SDD=SDD
67        if(NVAR_Exists(SDD)==0)
68                Variable/G SDD=3.84                                     //in meters
69        endif
70        NVAR lambda=lambda
71        if(NVAR_Exists(lambda)==0)
72                Variable/G lambda=6                             //angstroms
73        endif
74        NVAR updateInt=updateInt
75        if(NVAR_Exists(updateInt)==0)
76                Variable/G updateInt=5                  //seconds
77        endif
78        NVAR timeout=timeout
79        if(NVAR_Exists(timeout)==0)
80                Variable/G timeout=300          //seconds
81        endif
82        NVAR elapsed=elapsed
83        if(NVAR_Exists(elapsed)==0)
84                Variable/G elapsed=0
85        endif
86        NVAR totalCounts=totalCounts            //total detector counts
87        if(NVAR_Exists(totalCounts)==0)
88                Variable/G totalCounts=0
89        endif
90       
91        // set the explicit path to the data file on "relay" computer (the user will be propmted for this)
92        SVAR RT_fileStr=RT_fileStr
93        if(SVAR_Exists(RT_fileStr)==0)
94                String/G RT_fileStr=""
95        endif
96
97        // set the background task
98        AssignBackgroundTask()
99       
100        SetDataFolder root:
101End
102
103//sets the background task and period (in ticks)
104//
105Function AssignBackgroundTask()
106
107        Variable updateInt=NumVarOrDefault("root:myGlobals:RT:updateInt",5)
108        // set the background task
109        SetBackground BkgUpdateHST()
110        CtrlBackground period=(updateInt*60),noBurst=1          //noBurst prevents rapid "catch-up calls
111        return(0)
112End
113
114//draws the RT panel and enforces bounds on the SetVariable controls for update period and timeout
115//
116Proc RT_Panel()
117        PauseUpdate; Silent 1           // building window...
118        NewPanel /W=(500,350,802,531) /K=2
119        DoWindow/C RT_Panel
120        DoWindow/T RT_Panel,"Real Time Display Controls"
121        ModifyPanel cbRGB=(65535,52428,6168)
122        SetDrawLayer UserBack
123        SetDrawEnv fstyle= 1
124        DrawText 26,21,"Enter values for real-time display"
125        Button bkgStart,pos={171,54},size={120,20},proc=UpdateHSTButton,title="Start Updating"
126        Button bkgStart,help={"Starts or stops the updating of the real-time SANS image"}
127        SetVariable setvar_0,pos={15,29},size={100,15},proc=RT_Param_SetVarProc,title="X Center"
128        SetVariable setvar_0,help={"Set this to the current beamcenter x-coordinate (in pixels)"}
129        SetVariable setvar_0,limits={0,128,0},value= root:myGlobals:RT:xCtr
130        SetVariable setvar_1,pos={14,46},size={100,15},proc=RT_Param_SetVarProc,title="Y Center"
131        SetVariable setvar_1,help={"Set this to the current beamcenter y-coordinate (in pixels)"}
132        SetVariable setvar_1,limits={0,128,0},value= root:myGlobals:RT:yCtr
133        SetVariable setvar_2,pos={14,64},size={100,15},proc=RT_Param_SetVarProc,title="SDD (m)"
134        SetVariable setvar_2,help={"Set this to the sample-to-detector distance of the current instrument configuration"}
135        SetVariable setvar_2,limits={0,1600,0},value= root:myGlobals:RT:SDD
136        SetVariable setvar_3,pos={15,82},size={100,15},proc=RT_Param_SetVarProc,title="Lambda (A)"
137        SetVariable setvar_3,help={"Set this to the wavelength of the current instrument configuration"}
138        SetVariable setvar_3,limits={0,30,0},value= root:myGlobals:RT:lambda
139        SetVariable setvar_4,pos={11,116},size={150,15},proc=UpdateInt_SetVarProc,title="Update Interval (s)"
140        SetVariable setvar_4,help={"This is the period of the update"}
141        SetVariable setvar_4,limits={1,3600,0},value= root:myGlobals:RT:updateInt
142        SetVariable setvar_5,pos={11,135},size={150,15},title="Timeout Interval (s)"
143        SetVariable setvar_5,help={"After the timeout interval has expired, the update process will automatically stop"}
144        SetVariable setvar_5,limits={1,3600,0},value= root:myGlobals:RT:timeout
145        Button button_1,pos={170,29},size={120,20},proc=LoadRTButtonProc,title="Load Live Data"
146        Button button_1,help={"Load the data file for real-time display"}
147        Button button_2,pos={229,80},size={60,20},proc=RT_HelpButtonProc,title="Help"
148        Button button_2,help={"Display the help file for real-time controls"}
149        Button button_3,pos={230,105},size={60,20},proc=RT_DoneButtonProc,title="Done"
150        Button button_3,help={"Closes the panel and stops the updating process"}
151        SetVariable setvar_6,pos={11,153},size={200,15},title="Total Detector Counts"
152        SetVariable setvar_6,help={"Total counts on the detector, as displayed"}
153        SetVariable setvar_6,limits={0,Inf,0},value= root:myGlobals:RT:totalCounts
154EndMacro
155
156//
157Proc RT_HelpButtonProc(ctrlName) : ButtonControl
158        String ctrlName
159//      DoAlert 0,"the help file has not been written yet :-("
160        DisplayHelpTopic/K=1 "SANS Data Reduction Tutorial[Real Time Data Display]"
161End
162
163//close the panel gracefully, and stop the background task if necessary
164//
165Proc RT_DoneButtonProc(ctrlName) : ButtonControl
166        String ctrlName
167       
168        BackgroundInfo
169        if(V_Flag==2)           //task is currently running
170                CtrlBackground stop
171        endif
172        DoWindow/K RT_Panel
173End
174
175//prompts for the RT data file - only needs to be set once, then the user can start/stop
176//
177Function LoadRTButtonProc(ctrlName) : ButtonControl
178        String ctrlName
179
180        DoAlert 0,"The RealTime detector image is located on Bach/tmp/Run.hst"
181        Read_RT_File("Select the Run.hst file")
182        return(0)
183End
184
185// Sets "fake" header information to allow qx,qy scales on the graph, and to allow
186// averaging to be done on the real-time dataset
187//
188// keep in mind that only the select bits of header information that is USER-SUPPLIED
189// on the panel is available for calculations. The RT data arrives at the relay computer
190// with NO header, only the 128x128 data....
191//
192// see also FillFakeHeader() for a few constant header values ...
193//
194//
195// check on a case-by-case basis
196Function RT_Param_SetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
197        String ctrlName
198        Variable varNum
199        String varStr
200        String varName
201
202        Wave rw=$"root:RealTime:RealsRead"
203        if(WaveExists(rw)==0)
204                return(1)
205        Endif
206        strswitch(ctrlName)     // string switch
207                case "setvar_0":                //xCtr
208                        rw[16]=varNum
209                        break   
210                case "setvar_1":                //yCtr
211                        rw[17]=varNum
212                        break   
213                case "setvar_2":                //SDD
214                        rw[18]=varNum
215                        break
216                case "setvar_3":                //lambda
217                        rw[26]=varNum
218                        break
219        endswitch
220        //only update the graph if it is open, and is a RealTime display...
221        if(WinType("SANS_Data")==0)
222                return(0) //SANS_Data window not open
223        Endif
224        SVAR type=root:myGlobals:gDataDisplayType
225        if(cmpstr("RealTime",type)!=0)
226                return(0)               //display not RealTime
227        Endif
228        fRawWindowHook()                //force a redraw of the graph
229        DoWindow/F RT_Panel             //return panel to the front
230        return(0)
231End
232
233// (re)-sets the period of the update background task
234//
235Function UpdateInt_SetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
236        String ctrlName
237        Variable varNum
238        String varStr
239        String varName
240
241//      BackgroundInfo
242//      if(V_flag==2)
243//              CtrlBackground stop
244//      Endif
245
246        // quite surprised that you can change the period of repeat while the task is active
247        CtrlBackground period=(varNum*60),noBurst=1
248        return(0)
249End
250
251
252/////////////////////////////
253//simple, main entry procedure that will load a HST sans data file (not a work file)
254//into the RealTime dataFolder
255//(typically called from main panel button)
256//
257//(ununsed)
258Proc Load_RT_Data()
259        String msgStr = "Select a RT Ordela data file"
260        Read_RT_File(msgStr)
261End
262
263//function called by the main entry procedure (the load button)
264//sets global display variable, reads in the data, and displays it
265//aborts if no file was selected
266//
267//(re)-sets the GLOBAL path:filename of the RT file to update
268// also resets the path to the RT file, so that the dialog brings you back to the right spot
269//
270// reads the data in if all is OK
271//
272Function Read_RT_File(msgStr)
273        String msgStr
274
275        String filename="",pathStr=""
276        Variable refnum
277
278        //check for the path
279        PathInfo RT_Path
280        If(V_Flag==1)           //      /D does not open the file
281                Open/D/R/T="????"/M=(msgStr)/P=RT_Path refNum
282        else
283                Open/D/R/T="????"/M=(msgStr) refNum
284        endif
285        filename = S_FileName           //get the filename, or null if canceled from dialog
286        if(strlen(filename)==0)
287                //user cancelled, abort
288                SetDataFolder root:
289                Abort "No file selected, action aborted"
290        Endif
291        //set the globals and reset the RT_Path value
292        pathStr = GetPathStrFromfullName(filename)
293        NewPath/O RT_Path,pathStr
294        Variable/G root:RealTime:gIsLogScale = 0                //force data to linear scale (1st read)
295        String/G root:myGlobals:RT:RT_fileStr=filename  //full path:file of the Run.hst file to re-read
296        //read in the data
297        ReadOrdelaHST(filename)
298
299        //the calling macro must change the display type
300        String/G root:myGlobals:gDataDisplayType="RealTime"             //displayed data type is RealTime
301       
302        FillFakeHeader()                //uses info on the panel, if available
303
304        //data is displayed here, and needs header info
305       
306        fRawWindowHook()
307       
308        // set the SANS_Data graph to "live" mode to allow fast updating
309        //fRawWindowHook just drew the graph, so it should exist
310        ModifyGraph/W=SANS_Data live=1          //not much speed help...
311       
312        return(0)
313End
314
315//function that does the guts of reading the binary data file
316//fname is the full path:name;vers required to open the file
317//The final root:RealTime:data wave is the real
318//neutron counts and can be directly used
319//
320//returns 0 if read was ok
321//returns 1 if there was an error
322Function ReadOrdelaHST(fname)
323        String fname
324        //this function is for reading in RealTime data only, so it will always put data in RealTime folder
325        SetDataFolder "root:RealTime"   
326        //keep a string with the filename in the RealTime folder
327        String/G root:RealTime:fileList = "Real-Time Data Display"
328        //get log/linear state based on SANS_Data window
329        Variable isLogScale=NumVarOrDefault("root:RealTime:gIsLogScale", 0)
330        Variable/G root:RealTime:gIsLogScale = isLogScale               //creates if needed, "sets" to cur val if already exists
331       
332        Variable refNum=0,ii,p1,p2,tot,num=128
333        String str=""
334        Make/O/T/N=11 hdrLines
335        Make/O/I/N=(num*num) a1         // /I flag = 32 bit integer data
336       
337        //full filename and path is now passed in...
338        //actually open the file
339        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
340        if(refnum==0)           //FNF error, get out
341                DoAlert 0,"Could not find file: "+fname
342                Close/A
343                return(1)
344        endif
345        if(V_flag!=0)
346                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
347                Close/A
348                return(1)
349        Endif
350        // as of 12MAY03, the run.hst for real-time display has no header lines (M. Doucet)
351//      for(ii=0;ii<11;ii+=1)           //read (or skip) 11 header lines
352//              FReadLine refnum,str
353//              hdrLines[ii]=str
354//      endfor
355        // 4-byte integer binary data follows, num*num integer values
356        FBinRead/B=3/F=3 refnum,a1
357        //     
358        Close refnum
359       
360        //we want only the first [0,127][0,127] quadrant of the 256x256 image
361        // this is done most quickly by two successive redimension operations
362        // (the duplicate is for testing only)
363        //final redimension can make the data FP if desired..
364        //Redimension/N=(256,256) a1
365        Redimension/N=(128,128) a1
366
367        if(exists("root:RealTime:data")!=1)             //wave DN exist
368                Make/O/N=(128,128) $"root:RealTime:data"
369        endif
370        WAVE data=$"root:RealTime:data"
371        Duplicate/O data,$"root:RealTime:linear_data"
372        WAVE lin_data=$"root:RealTime:linear_data"
373        lin_data=a1
374        if(isLogScale)
375                data=log(a1)
376        else
377                data=a1
378        Endif
379       
380        KillWaves/Z a1 
381       
382        //return the data folder to root
383        SetDataFolder root:
384       
385        Return 0
386End
387
388// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
389// pay attention to what is/not to be trusted due to "fake" information
390//
391Function FillFakeHeader()
392
393        Make/O/N=23 $"root:RealTime:IntegersRead"
394        Make/O/N=52 $"root:RealTime:RealsRead"
395        Make/O/T/N=11 $"root:RealTime:TextRead"
396       
397        Wave intw=$"root:RealTime:IntegersRead"
398        Wave realw=$"root:RealTime:RealsRead"
399        Wave/T textw=$"root:RealTime:TextRead"
400       
401        //Put in appropriate "fake" values
402        // first 4 are user-defined on the Real Time control panel, so user has the opportunity to change these values.
403        //
404        realw[16]=NumVarOrDefault("root:myGlobals:RT:xCtr", 64.5)               //xCtr(pixels)
405        realw[17]=NumVarOrDefault("root:myGlobals:RT:yCtr", 64.5)               //yCtr (pixels)
406        realw[18]=NumVarOrDefault("root:myGlobals:RT:SDD", 5)           //SDD (m)
407        realw[26]=NumVarOrDefault("root:myGlobals:RT:lambda", 6)                //wavelength (A)
408        //
409        // necessary values
410        realw[10]=5                     //detector calibration constants, needed for averaging
411        realw[11]=10000
412        realw[13]=5
413        realw[14]=10000
414        //
415        // used in the resolution calculation, ONLY here to keep the routine from crashing
416        realw[20]=65            //det size
417        realw[27]=0.15  //delta lambda
418        realw[21]=50.8  //BS size
419        realw[23]=50            //A1
420        realw[24]=12.7  //A2
421        realw[25]=8.57  //A1A2 distance
422        realw[4]=1              //trans
423        realw[3]=0              //atten
424        realw[5]=0.1            //thick
425        //
426        //
427        realw[0]=1e8            //def mon cts
428
429        // fake values to get valid deadtime and detector constants
430        //
431        textw[9]="ORNL  "               //6 characters
432        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
433       
434        return(0)
435End
436
437// action procedure to start/stop the updating process.
438//checks for update display graph, current background task, etc..
439// then update the button and at last controls the background task
440//
441Function UpdateHSTButton(ctrlName) : ButtonControl
442        String ctrlName
443       
444        //check that the RT window is open, and that the display type is "RealTime"
445        if(WinType("SANS_Data")==0)
446                return(1) //SANS_Data window not open
447        Endif
448        SVAR type=root:myGlobals:gDataDisplayType
449        if(cmpstr("RealTime",type)!=0)
450                return(1)               //display not RealTime
451        Endif
452        //check the current state of the background task
453        BackgroundInfo          //returns 0 if no task defined, 1 if idle, 2 if running
454        if(V_flag==0)
455                AssignBackgroundTask()
456        Endif
457       
458        String Str=""
459        //control the task, and update the button text
460        if (cmpstr(ctrlName,"bkgStart") == 0)
461                Button $ctrlName,win=RT_Panel,title="Stop Updating",rename=bkgStop             
462        //      Start the updating - BkgUpdateHST() has been designated as the background task
463                CtrlBackground start
464        else
465                Button $ctrlName,win=RT_Panel,title="Start Updating",rename=bkgStart
466                NVAR elapsed=root:myGlobals:RT:elapsed
467                elapsed=0       //reset the timer
468        //      Stop the updating
469                CtrlBackground stop
470        endif
471        return(0)
472End
473
474
475// THIS IS THE BACKGROUND TASK
476//
477// simply re-reads the designated .hst file (which can be located anywhere, as long as it
478// appears as a local disk)
479// return value of 0 continues background execution
480// return value of 1 turns background task off
481//
482Function BkgUpdateHST()
483
484        WAVE data = $"root:RealTime:data"
485        NVAR elapsed=root:myGlobals:RT:elapsed
486        NVAR timeout=root:myGlobals:RT:timeout
487        NVAR updateInt=root:myGlobals:RT:updateInt
488        NVAR totCounts=root:myGlobals:RT:totalCounts
489       
490        Variable err=0
491//      Variable t1=ticks
492        SVAR RT_fileStr=root:myGlobals:RT:RT_fileStr
493       
494        elapsed += updateInt
495//      get the new data by re-reading the datafile from the relay computer
496        if(elapsed<timeout)
497       
498                if(WinType("SANS_Data")==0)
499                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
500                        return(1) //SANS_Data window not open
501                Endif
502                SVAR type=root:myGlobals:gDataDisplayType
503                if(cmpstr("RealTime",type)!=0)
504                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
505                        return(1)               //display not RealTime
506                Endif
507                SVAR title=root:myGlobals:gCurDispFile
508                title="Reading new data..."
509                ControlUpdate/W=SANS_Data/A
510               
511                err = ReadOrdelaHST(RT_fileStr)
512                if(err==1)
513                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
514                        return(err)     //file not found
515                Endif
516                // for testing only...
517//              data += abs(enoise(data))
518                //
519                MapSliderProc("reset", 0, 1)
520               
521                title="Real-Time Data Display"
522                //sum the total counts, global variable will automatically update
523                WAVE/Z linear_data = $"root:RealTime:linear_data"
524                if(WaveExists(linear_data))
525                        totCounts = sum(linear_data, -Inf, Inf )
526                else
527                        WAVE/Z data = $"root:RealTime:data"
528                        totCounts = sum(data, -Inf, Inf )
529                endif
530               
531//              print "Bkg task time (s) =",(ticks-t1)/60.15
532                return 0                //keep the process going
533        else
534                //timeout, stop the process, reset the button label
535                elapsed=0
536                Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
537                return(1)
538        endif
539       
540End
541
Note: See TracBrowser for help on using the repository browser.