source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/RealTimeUpdate_RT.ipf @ 482

Last change on this file since 482 was 482, checked in by ajj, 14 years ago
  • Re-introduce live data display
  • Fix to load real data file
File size: 17.6 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.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:Packages:NIST: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,480) /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,31},size={150,20},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,56},size={150,20},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={250,2},size={30,20},proc=RT_HelpButtonProc,title="?"
148        Button button_2,help={"Display the help file for real-time controls"}
149        Button button_3,pos={230,80},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,82},size={200,20},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 somewhere"
181        Read_RT_File("Select the Live Data 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:Packages:NIST: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:Packages:NIST: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        ReadHeaderAndData(filename)
300        Raw_to_Work("RealTime")
301
302        //the calling macro must change the display type
303        String/G root:myGlobals:gDataDisplayType="RealTime"             //displayed data type is RealTime
304       
305        //FillFakeHeader()              //uses info on the panel, if available
306
307        //data is displayed here, and needs header info
308       
309        fRawWindowHook()
310       
311        // set the SANS_Data graph to "live" mode to allow fast updating
312        //fRawWindowHook just drew the graph, so it should exist
313        ModifyGraph/W=SANS_Data live=1          //not much speed help...
314       
315        return(0)
316End
317
318//function that does the guts of reading the binary data file
319//fname is the full path:name;vers required to open the file
320//The final root:Packages:NIST:RealTime:data wave is the real
321//neutron counts and can be directly used
322//
323//returns 0 if read was ok
324//returns 1 if there was an error
325Function ReadOrdelaHST(fname)
326        String fname
327        //this function is for reading in RealTime data only, so it will always put data in RealTime folder
328        SetDataFolder "root:Packages:NIST:RealTime"     
329        //keep a string with the filename in the RealTime folder
330        String/G root:Packages:NIST:RealTime:fileList = "Real-Time Data Display"
331        //get log/linear state based on SANS_Data window
332        Variable isLogScale=NumVarOrDefault("root:Packages:NIST:RealTime:gIsLogScale", 0)
333        Variable/G root:Packages:NIST:RealTime:gIsLogScale = isLogScale         //creates if needed, "sets" to cur val if already exists
334       
335        Variable refNum=0,ii,p1,p2,tot,num=128
336        String str=""
337        Make/O/T/N=11 hdrLines
338        Make/O/I/N=(num*num) a1         // /I flag = 32 bit integer data
339       
340        //full filename and path is now passed in...
341        //actually open the file
342        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
343        if(refnum==0)           //FNF error, get out
344                DoAlert 0,"Could not find file: "+fname
345                Close/A
346                return(1)
347        endif
348        if(V_flag!=0)
349                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
350                Close/A
351                return(1)
352        Endif
353        // as of 12MAY03, the run.hst for real-time display has no header lines (M. Doucet)
354//      for(ii=0;ii<11;ii+=1)           //read (or skip) 11 header lines
355//              FReadLine refnum,str
356//              hdrLines[ii]=str
357//      endfor
358        // 4-byte integer binary data follows, num*num integer values
359        FBinRead/B=3/F=3 refnum,a1
360        //     
361        Close refnum
362       
363        //we want only the first [0,127][0,127] quadrant of the 256x256 image
364        // this is done most quickly by two successive redimension operations
365        // (the duplicate is for testing only)
366        //final redimension can make the data FP if desired..
367        //Redimension/N=(256,256) a1
368        Redimension/N=(128,128) a1
369
370        if(exists("root:Packages:NIST:RealTime:data")!=1)               //wave DN exist
371                Make/O/N=(128,128) $"root:Packages:NIST:RealTime:data"
372        endif
373        WAVE data=$"root:Packages:NIST:RealTime:data"
374        Duplicate/O data,$"root:Packages:NIST:RealTime:linear_data"
375        WAVE lin_data=$"root:Packages:NIST:RealTime:linear_data"
376        lin_data=a1
377        if(isLogScale)
378                data=log(a1)
379        else
380                data=a1
381        Endif
382       
383        KillWaves/Z a1 
384       
385        //return the data folder to root
386        SetDataFolder root:
387       
388        Return 0
389End
390
391// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
392// pay attention to what is/not to be trusted due to "fake" information
393//
394Function FillFakeHeader()
395
396        Make/O/N=23 $"root:Packages:NIST:RealTime:IntegersRead"
397        Make/O/N=52 $"root:Packages:NIST:RealTime:RealsRead"
398        Make/O/T/N=11 $"root:Packages:NIST:RealTime:TextRead"
399       
400        Wave intw=$"root:Packages:NIST:RealTime:IntegersRead"
401        Wave realw=$"root:Packages:NIST:RealTime:RealsRead"
402        Wave/T textw=$"root:Packages:NIST:RealTime:TextRead"
403       
404        //Put in appropriate "fake" values
405        // first 4 are user-defined on the Real Time control panel, so user has the opportunity to change these values.
406        //
407        realw[16]=NumVarOrDefault("root:myGlobals:RT:xCtr", 64.5)               //xCtr(pixels)
408        realw[17]=NumVarOrDefault("root:myGlobals:RT:yCtr", 64.5)               //yCtr (pixels)
409        realw[18]=NumVarOrDefault("root:myGlobals:RT:SDD", 5)           //SDD (m)
410        realw[26]=NumVarOrDefault("root:myGlobals:RT:lambda", 6)                //wavelength (A)
411        //
412        // necessary values
413        realw[10]=5                     //detector calibration constants, needed for averaging
414        realw[11]=10000
415        realw[13]=5
416        realw[14]=10000
417        //
418        // used in the resolution calculation, ONLY here to keep the routine from crashing
419        realw[20]=65            //det size
420        realw[27]=0.15  //delta lambda
421        realw[21]=50.8  //BS size
422        realw[23]=50            //A1
423        realw[24]=12.7  //A2
424        realw[25]=8.57  //A1A2 distance
425        realw[4]=1              //trans
426        realw[3]=0              //atten
427        realw[5]=0.1            //thick
428        //
429        //
430        realw[0]=1e8            //def mon cts
431
432        // fake values to get valid deadtime and detector constants
433        //
434        textw[9]="ORNL  "               //6 characters
435        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
436       
437        return(0)
438End
439
440// action procedure to start/stop the updating process.
441//checks for update display graph, current background task, etc..
442// then update the button and at last controls the background task
443//
444Function UpdateHSTButton(ctrlName) : ButtonControl
445        String ctrlName
446       
447        //check that the RT window is open, and that the display type is "RealTime"
448        if(WinType("SANS_Data")==0)
449                return(1) //SANS_Data window not open
450        Endif
451        SVAR type=root:myGlobals:gDataDisplayType
452        if(cmpstr("RealTime",type)!=0)
453                return(1)               //display not RealTime
454        Endif
455        //check the current state of the background task
456        BackgroundInfo          //returns 0 if no task defined, 1 if idle, 2 if running
457        if(V_flag==0)
458                AssignBackgroundTask()
459        Endif
460       
461        String Str=""
462        //control the task, and update the button text
463        if (cmpstr(ctrlName,"bkgStart") == 0)
464                Button $ctrlName,win=RT_Panel,title="Stop Updating",rename=bkgStop             
465        //      Start the updating - BkgUpdateHST() has been designated as the background task
466                CtrlBackground start
467        else
468                Button $ctrlName,win=RT_Panel,title="Start Updating",rename=bkgStart
469                NVAR elapsed=root:myGlobals:RT:elapsed
470                elapsed=0       //reset the timer
471        //      Stop the updating
472                CtrlBackground stop
473        endif
474        return(0)
475End
476
477
478// THIS IS THE BACKGROUND TASK
479//
480// simply re-reads the designated .hst file (which can be located anywhere, as long as it
481// appears as a local disk)
482// return value of 0 continues background execution
483// return value of 1 turns background task off
484//
485Function BkgUpdateHST()
486
487        WAVE data = $"root:Packages:NIST:RealTime:data"
488        NVAR elapsed=root:myGlobals:RT:elapsed
489        NVAR timeout=root:myGlobals:RT:timeout
490        NVAR updateInt=root:myGlobals:RT:updateInt
491        NVAR totCounts=root:myGlobals:RT:totalCounts
492       
493        Variable err=0
494//      Variable t1=ticks
495        SVAR RT_fileStr=root:myGlobals:RT:RT_fileStr
496       
497        elapsed += updateInt
498//      get the new data by re-reading the datafile from the relay computer
499        if(elapsed<timeout)
500       
501                if(WinType("SANS_Data")==0)
502                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
503                        return(1) //SANS_Data window not open
504                Endif
505                SVAR type=root:myGlobals:gDataDisplayType
506                if(cmpstr("RealTime",type)!=0)
507                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
508                        return(1)               //display not RealTime
509                Endif
510                SVAR title=root:myGlobals:gCurDispFile
511                title="Reading new data..."
512                ControlUpdate/W=SANS_Data/A
513               
514                //err = ReadOrdelaHST(RT_fileStr)
515                err = ReadHeaderAndData(RT_fileStr)
516                if(err==1)
517                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
518                        return(err)     //file not found
519                Endif
520                Raw_to_work("RealTime")
521                // for testing only...
522//              data += abs(enoise(data))
523                //
524                MapSliderProc("reset", 0, 1)
525               
526                title="Real-Time Data Display"
527                //sum the total counts, global variable will automatically update
528                WAVE/Z linear_data = $"root:Packages:NIST:RealTime:linear_data"
529                if(WaveExists(linear_data))
530                        totCounts = sum(linear_data, -Inf, Inf )
531                else
532                        WAVE/Z data = $"root:Packages:NIST:RealTime:data"
533                        totCounts = sum(data, -Inf, Inf )
534                endif
535               
536//              print "Bkg task time (s) =",(ticks-t1)/60.15
537                return 0                //keep the process going
538        else
539                //timeout, stop the process, reset the button label
540                elapsed=0
541                Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
542                return(1)
543        endif
544       
545End
Note: See TracBrowser for help on using the repository browser.