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

Last change on this file since 575 was 570, checked in by srkline, 13 years ago

Change (1):
In preparation for release, updated pragma IgorVersion?=6.1 in all procedures

Change (2):
As a side benefit of requiring 6.1, we can use the MultiThread? keyword to thread any model function we like. The speed benefit is only noticeable on functions that require at least one integration and at least 100 points (resolution smearing is NOT threaded, too many threadSafe issues, too little benefit). I have chosen to use the MultiThread? only on the XOP assignment. In the Igor code there are too many functions that are not explicitly declared threadsafe, making for a mess.

File size: 29.9 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
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        DoWindow/K RT_Panel
30        InitFolders()
31        InitFakeProtocols()
32        InitGlobals()
33        InitFacilityGlobals()
34
35        // specific for RealTime display
36        //set the current display type to RealTime
37        String/G root:myGlobals:gDataDisplayType = "RealTime"
38        // draw the RealTime control panel
39        Show_RealTime_Panel()
40End
41
42// Proc to bring the RT control panel to the front, always initializes the panel
43// - always initialize to make sure that the background task is properly set
44//
45Proc Show_RealTime_Panel()
46        Init_RT()               //always init, data folders and globals are created here
47        DoWindow/F RT_Panel
48        if(V_flag==0)
49                RT_Panel()
50        Endif
51End
52
53// folder and globals that are needed ONLY for the RT process
54//
55Function Init_RT()
56        //create folders
57        NewDataFolder/O root:Packages:NIST:RealTime
58        NewDataFolder/O/S root:myGlobals:RT
59        //create default globals only if they don't already exist, so you don't overwrite user-entered values.
60        NVAR/Z xCtr=xCtr
61        if(NVAR_Exists(xctr)==0)
62                Variable/G xCtr=110                     //pixels
63        endif
64        NVAR/Z yCtr=yCtr
65        if(NVAR_Exists(yCtr)==0)
66                Variable/G yCtr=64
67        endif
68        NVAR/Z SDD=SDD
69        if(NVAR_Exists(SDD)==0)
70                Variable/G SDD=3.84                                     //in meters
71        endif
72        NVAR/Z lambda=lambda
73        if(NVAR_Exists(lambda)==0)
74                Variable/G lambda=6                             //angstroms
75        endif
76        NVAR/Z updateInt=updateInt
77        if(NVAR_Exists(updateInt)==0)
78                Variable/G updateInt=5                  //seconds
79        endif
80        NVAR/Z timeout=timeout
81        if(NVAR_Exists(timeout)==0)
82                Variable/G timeout=300          //seconds
83        endif
84        NVAR/Z elapsed=elapsed
85        if(NVAR_Exists(elapsed)==0)
86                Variable/G elapsed=0
87        endif
88        NVAR/Z totalCounts=totalCounts          //total detector counts
89        if(NVAR_Exists(totalCounts)==0)
90                Variable/G totalCounts=0
91        endif
92        NVAR/Z countTime = root:myGlobals:RT:countTime
93        if(NVAR_Exists(countTime)==0)
94                Variable/G countTime = 0
95        endif
96        NVAR/Z countRate = root:myGlobals:RT:countRate
97        if(NVAR_Exists(countRate)==0)
98                Variable/G countRate = 0
99        endif
100        NVAR/Z monitorCountRate = root:myGlobals:RT:monitorCountRate
101        if(NVAR_Exists(monitorCountRate)==0)
102                Variable/G monitorCountRate = 0
103        endif
104        NVAR/Z monitorCounts = root:myGlobals:RT:monitorCounts
105        if(NVAR_Exists(monitorCounts)==0)
106                Variable/G monitorCounts = 0
107        endif
108       
109        // set the explicit path to the data file on "relay" computer (the user will be propmted for this)
110        SVAR/Z RT_fileStr=RT_fileStr
111        if(SVAR_Exists(RT_fileStr)==0)
112                String/G RT_fileStr=""
113        endif
114
115        // set the background task
116        AssignBackgroundTask()
117       
118        SetDataFolder root:
119End
120
121//sets the background task and period (in ticks)
122//
123Function AssignBackgroundTask()
124
125        Variable updateInt=NumVarOrDefault("root:myGlobals:RT:updateInt",5)
126        // set the background task
127        SetBackground BkgUpdateHST()
128        CtrlBackground period=(updateInt*60),noBurst=0          //noBurst prevents rapid "catch-up calls
129        return(0)
130End
131
132//draws the RT panel and enforces bounds on the SetVariable controls for update period and timeout
133//
134Proc RT_Panel()
135        PauseUpdate; Silent 1           // building window...
136        NewPanel /W=(300,350,602,580) /K=2
137        DoWindow/C RT_Panel
138        DoWindow/T RT_Panel,"Real Time Display Controls"
139        ModifyPanel cbRGB=(65535,52428,6168)
140        SetDrawLayer UserBack
141        SetDrawEnv fstyle= 1
142        DrawText 26,21,"Enter values for real-time display"
143        Button bkgStart,pos={171,54},size={120,20},proc=UpdateHSTButton,title="Start Updating"
144        Button bkgStart,help={"Starts or stops the updating of the real-time SANS image"}
145//      SetVariable setvar_0,pos={15,29},size={100,15},proc=RT_Param_SetVarProc,title="X Center"
146//      SetVariable setvar_0,help={"Set this to the current beamcenter x-coordinate (in pixels)"}
147//      SetVariable setvar_0,limits={0,128,0},value= root:myGlobals:RT:xCtr
148//      SetVariable setvar_1,pos={14,46},size={100,15},proc=RT_Param_SetVarProc,title="Y Center"
149//      SetVariable setvar_1,help={"Set this to the current beamcenter y-coordinate (in pixels)"}
150//      SetVariable setvar_1,limits={0,128,0},value= root:myGlobals:RT:yCtr
151//      SetVariable setvar_2,pos={14,64},size={100,15},proc=RT_Param_SetVarProc,title="SDD (m)"
152//      SetVariable setvar_2,help={"Set this to the sample-to-detector distance of the current instrument configuration"}
153//      SetVariable setvar_2,limits={0,1600,0},value= root:myGlobals:RT:SDD
154//      SetVariable setvar_3,pos={15,82},size={100,15},proc=RT_Param_SetVarProc,title="Lambda (A)"
155//      SetVariable setvar_3,help={"Set this to the wavelength of the current instrument configuration"}
156//      SetVariable setvar_3,limits={0,30,0},value= root:myGlobals:RT:lambda
157        SetVariable setvar_4,pos={11,31},size={150,20},proc=UpdateInt_SetVarProc,title="Update Interval (s)"
158        SetVariable setvar_4,help={"This is the period of the update"}
159        SetVariable setvar_4,limits={1,3600,0},value= root:myGlobals:RT:updateInt
160//      SetVariable setvar_5,pos={11,56},size={150,20},title="Timeout Interval (s)"
161//      SetVariable setvar_5,help={"After the timeout interval has expired, the update process will automatically stop"}
162//      SetVariable setvar_5,limits={1,3600,0},value= root:myGlobals:RT:timeout
163        Button button_1,pos={170,29},size={120,20},proc=LoadRTButtonProc,title="Load Live Data"
164        Button button_1,help={"Load the data file for real-time display"}
165        Button button_2,pos={250,2},size={30,20},proc=RT_HelpButtonProc,title="?"
166        Button button_2,help={"Display the help file for real-time controls"}
167        //Button button_3,pos={230,80},size={60,20},proc=RT_DoneButtonProc,title="Done"
168        //Button button_3,help={"Closes the panel and stops the updating process"}
169        SetVariable setvar_6,pos={11,105},size={250,20},title="Total Detector Counts"
170        SetVariable setvar_6,help={"Total counts on the detector, as displayed"},noedit=1
171        SetVariable setvar_6,limits={0,Inf,0},value= root:myGlobals:RT:totalCounts
172        SetVariable setvar_7,pos={11,82},size={250,20},title="                  Count Time"
173        SetVariable setvar_7,help={"Count time, as displayed"},noedit=1
174        SetVariable setvar_7,limits={0,Inf,0},value= root:myGlobals:RT:countTime
175        SetVariable setvar_8,pos={11,127},size={250,20},title="  Detector Count Rate"
176        SetVariable setvar_8,help={"Count rate, as displayed"},noedit=1
177        SetVariable setvar_8,limits={0,Inf,0},value= root:myGlobals:RT:countRate
178        SetVariable setvar_9,pos={11,149},size={250,20},title="           Monitor Counts"
179        SetVariable setvar_9,help={"Count rate, as displayed"},noedit=1
180        SetVariable setvar_9,limits={0,Inf,0},value= root:myGlobals:RT:monitorCounts
181        SetVariable setvar_10,pos={11,171},size={250,20},title="    Monitor Count Rate"
182        SetVariable setvar_10,help={"Count rate, as displayed"},noedit=1
183        SetVariable setvar_10,limits={0,Inf,0},value= root:myGlobals:RT:monitorCountRate
184EndMacro
185
186//
187Proc RT_HelpButtonProc(ctrlName) : ButtonControl
188        String ctrlName
189//      DoAlert 0,"the help file has not been written yet :-("
190        DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[Real Time Data Display]"
191End
192
193//close the panel gracefully, and stop the background task if necessary
194//
195Proc RT_DoneButtonProc(ctrlName) : ButtonControl
196        String ctrlName
197       
198        BackgroundInfo
199        if(V_Flag==2)           //task is currently running
200                CtrlBackground stop
201        endif
202        DoWindow/K RT_Panel
203End
204
205//prompts for the RT data file - only needs to be set once, then the user can start/stop
206//
207Function LoadRTButtonProc(ctrlName) : ButtonControl
208        String ctrlName
209
210        DoAlert 0,"The RealTime detector image is located on charlotte"
211        Read_RT_File("Select the Live Data file")
212        return(0)
213End
214
215// Sets "fake" header information to allow qx,qy scales on the graph, and to allow
216// averaging to be done on the real-time dataset
217//
218// keep in mind that only the select bits of header information that is USER-SUPPLIED
219// on the panel is available for calculations. The RT data arrives at the relay computer
220// with NO header, only the 128x128 data....
221//
222// see also FillFakeHeader() for a few constant header values ...
223//
224//
225// check on a case-by-case basis
226Function RT_Param_SetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
227        String ctrlName
228        Variable varNum
229        String varStr
230        String varName
231
232        Wave rw=$"root:Packages:NIST:RealTime:RealsRead"
233        if(WaveExists(rw)==0)
234                return(1)
235        Endif
236        strswitch(ctrlName)     // string switch
237                case "setvar_0":                //xCtr
238                        rw[16]=varNum
239                        break   
240                case "setvar_1":                //yCtr
241                        rw[17]=varNum
242                        break   
243                case "setvar_2":                //SDD
244                        rw[18]=varNum
245                        break
246                case "setvar_3":                //lambda
247                        rw[26]=varNum
248                        break
249        endswitch
250        //only update the graph if it is open, and is a RealTime display...
251        if(WinType("SANS_Data")==0)
252                return(0) //SANS_Data window not open
253        Endif
254        SVAR type=root:myGlobals:gDataDisplayType
255        if(cmpstr("RealTime",type)!=0)
256                return(0)               //display not RealTime
257        Endif
258        fRawWindowHook()                //force a redraw of the graph
259        DoWindow/F RT_Panel             //return panel to the front
260        return(0)
261End
262
263// (re)-sets the period of the update background task
264//
265Function UpdateInt_SetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
266        String ctrlName
267        Variable varNum
268        String varStr
269        String varName
270
271//      BackgroundInfo
272//      if(V_flag==2)
273//              CtrlBackground stop
274//      Endif
275
276        // quite surprised that you can change the period of repeat while the task is active
277        CtrlBackground period=(varNum*60),noBurst=1
278        return(0)
279End
280
281
282/////////////////////////////
283//simple, main entry procedure that will load a HST sans data file (not a work file)
284//into the RealTime dataFolder
285//(typically called from main panel button)
286//
287//(ununsed)
288Proc Load_RT_Data()
289        String msgStr = "Select a RT Ordela data file"
290        Read_RT_File(msgStr)
291End
292
293//function called by the main entry procedure (the load button)
294//sets global display variable, reads in the data, and displays it
295//aborts if no file was selected
296//
297//(re)-sets the GLOBAL path:filename of the RT file to update
298// also resets the path to the RT file, so that the dialog brings you back to the right spot
299//
300// reads the data in if all is OK
301//
302Function Read_RT_File(msgStr)
303        String msgStr
304
305        String filename="",pathStr=""
306        Variable refnum
307
308        //check for the path
309        PathInfo RT_Path
310        If(V_Flag==1)           //      /D does not open the file
311                Open/D/R/T="????"/M=(msgStr)/P=RT_Path refNum
312        else
313                Open/D/R/T="????"/M=(msgStr) refNum
314        endif
315        filename = S_FileName           //get the filename, or null if canceled from dialog
316        if(strlen(filename)==0)
317                //user cancelled, abort
318                SetDataFolder root:
319                Abort "No file selected, action aborted"
320        Endif
321        //set the globals and reset the RT_Path value
322        pathStr = GetPathStrFromfullName(filename)
323        NewPath/O RT_Path,pathStr
324        Variable/G root:Packages:NIST:RealTime:gIsLogScale = 0          //force data to linear scale (1st read)
325        String/G root:myGlobals:RT:RT_fileStr=filename  //full path:file of the Run.hst file to re-read
326        //read in the data
327        //ReadOrdelaHST(filename)
328       
329        //ReadHeaderAndData(filename)
330        //Raw_to_Work("RealTime")
331        ReadRTAndData(filename)
332
333        //the calling macro must change the display type
334        String/G root:myGlobals:gDataDisplayType="RealTime"             //displayed data type is RealTime
335       
336        //FillFakeHeader()              //uses info on the panel, if available
337
338        //data is displayed here, and needs header info
339        WAVE data = $"root:Packages:NIST:RealTime:data"
340        NVAR totCounts = root:myGlobals:RT:totalCounts
341        NVAR countTime = root:myGlobals:RT:countTime
342        NVAR countRate = root:myGlobals:RT:countRate
343        NVAR monitorCounts = root:myGlobals:RT:monitorCounts
344        NVAR monitorCountRate = root:myGlobals:RT:monitorCountRate
345        SVAR title = root:myGlobals:gCurDispFile
346       
347        title="Real-Time : "+filename
348        //sum the total counts, global variable will automatically update
349        WAVE/Z linear_data = $"root:Packages:NIST:RealTime:linear_data"
350        if(WaveExists(linear_data))
351                totCounts = sum(linear_data, -Inf, Inf )
352        else
353                WAVE/Z data = $"root:Packages:NIST:RealTime:data"
354                totCounts = sum(data, -Inf, Inf )
355        endif
356        //Update other live values
357        Wave intw = root:Packages:NIST:RealTime:IntegersRead
358        Wave realw = root:Packages:NIST:RealTime:RealsRead
359        countTime = intw[2]
360        countRate = totCounts/countTime
361        monitorCounts = realw[0]
362        monitorCountRate = monitorCounts/countTime
363
364        fRawWindowHook()
365       
366        // set the SANS_Data graph to "live" mode to allow fast updating
367        //fRawWindowHook just drew the graph, so it should exist
368        ModifyGraph/W=SANS_Data live=1          //not much speed help...
369       
370        return(0)
371End
372
373//function that does the guts of reading the binary data file
374//fname is the full path:name;vers required to open the file
375//The final root:Packages:NIST:RealTime:data wave is the real
376//neutron counts and can be directly used
377//
378//returns 0 if read was ok
379//returns 1 if there was an error
380Function ReadOrdelaHST(fname)
381        String fname
382        //this function is for reading in RealTime data only, so it will always put data in RealTime folder
383        SetDataFolder "root:Packages:NIST:RealTime"     
384        //keep a string with the filename in the RealTime folder
385        String/G root:Packages:NIST:RealTime:fileList = "Real-Time Data Display"
386        //get log/linear state based on SANS_Data window
387        Variable isLogScale=NumVarOrDefault("root:Packages:NIST:RealTime:gIsLogScale", 0)
388        Variable/G root:Packages:NIST:RealTime:gIsLogScale = isLogScale         //creates if needed, "sets" to cur val if already exists
389       
390        Variable refNum=0,ii,p1,p2,tot,num=128
391        String str=""
392        Make/O/T/N=11 hdrLines
393        Make/O/I/N=(num*num) a1         // /I flag = 32 bit integer data
394       
395        //full filename and path is now passed in...
396        //actually open the file
397        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
398        if(refnum==0)           //FNF error, get out
399                DoAlert 0,"Could not find file: "+fname
400                Close/A
401                return(1)
402        endif
403        if(V_flag!=0)
404                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
405                Close/A
406                return(1)
407        Endif
408        // as of 12MAY03, the run.hst for real-time display has no header lines (M. Doucet)
409//      for(ii=0;ii<11;ii+=1)           //read (or skip) 11 header lines
410//              FReadLine refnum,str
411//              hdrLines[ii]=str
412//      endfor
413        // 4-byte integer binary data follows, num*num integer values
414        FBinRead/B=3/F=3 refnum,a1
415        //     
416        Close refnum
417       
418        //we want only the first [0,127][0,127] quadrant of the 256x256 image
419        // this is done most quickly by two successive redimension operations
420        // (the duplicate is for testing only)
421        //final redimension can make the data FP if desired..
422        //Redimension/N=(256,256) a1
423        Redimension/N=(128,128) a1
424
425        if(exists("root:Packages:NIST:RealTime:data")!=1)               //wave DN exist
426                Make/O/N=(128,128) $"root:Packages:NIST:RealTime:data"
427        endif
428        WAVE data=$"root:Packages:NIST:RealTime:data"
429        Duplicate/O data,$"root:Packages:NIST:RealTime:linear_data"
430        WAVE lin_data=$"root:Packages:NIST:RealTime:linear_data"
431        lin_data=a1
432        if(isLogScale)
433                data=log(a1)
434        else
435                data=a1
436        Endif
437       
438        KillWaves/Z a1 
439       
440        //return the data folder to root
441        SetDataFolder root:
442       
443        Return 0
444End
445
446// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
447// pay attention to what is/not to be trusted due to "fake" information
448//
449Function FillFakeHeader()
450
451        Make/O/N=23 $"root:Packages:NIST:RealTime:IntegersRead"
452        Make/O/N=52 $"root:Packages:NIST:RealTime:RealsRead"
453        Make/O/T/N=11 $"root:Packages:NIST:RealTime:TextRead"
454       
455        Wave intw=$"root:Packages:NIST:RealTime:IntegersRead"
456        Wave realw=$"root:Packages:NIST:RealTime:RealsRead"
457        Wave/T textw=$"root:Packages:NIST:RealTime:TextRead"
458       
459        //Put in appropriate "fake" values
460        // first 4 are user-defined on the Real Time control panel, so user has the opportunity to change these values.
461        //
462        realw[16]=NumVarOrDefault("root:myGlobals:RT:xCtr", 64.5)               //xCtr(pixels)
463        realw[17]=NumVarOrDefault("root:myGlobals:RT:yCtr", 64.5)               //yCtr (pixels)
464        realw[18]=NumVarOrDefault("root:myGlobals:RT:SDD", 5)           //SDD (m)
465        realw[26]=NumVarOrDefault("root:myGlobals:RT:lambda", 6)                //wavelength (A)
466        //
467        // necessary values
468        realw[10]=5                     //detector calibration constants, needed for averaging
469        realw[11]=10000
470        realw[13]=5
471        realw[14]=10000
472        //
473        // used in the resolution calculation, ONLY here to keep the routine from crashing
474        realw[20]=65            //det size
475        realw[27]=0.15  //delta lambda
476        realw[21]=50.8  //BS size
477        realw[23]=50            //A1
478        realw[24]=12.7  //A2
479        realw[25]=8.57  //A1A2 distance
480        realw[4]=1              //trans
481        realw[3]=0              //atten
482        realw[5]=0.1            //thick
483        //
484        //
485        realw[0]=1e8            //def mon cts
486
487        // fake values to get valid deadtime and detector constants
488        //
489        textw[9]="ORNL  "               //6 characters
490        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
491       
492        return(0)
493End
494
495// action procedure to start/stop the updating process.
496//checks for update display graph, current background task, etc..
497// then update the button and at last controls the background task
498//
499Function UpdateHSTButton(ctrlName) : ButtonControl
500        String ctrlName
501       
502        //check that the RT window is open, and that the display type is "RealTime"
503        if(WinType("SANS_Data")==0)
504                return(1) //SANS_Data window not open
505        Endif
506        SVAR type=root:myGlobals:gDataDisplayType
507        if(cmpstr("RealTime",type)!=0)
508                return(1)               //display not RealTime
509        Endif
510        //check the current state of the background task
511        BackgroundInfo          //returns 0 if no task defined, 1 if idle, 2 if running
512        if(V_flag==0)
513                AssignBackgroundTask()
514        Endif
515       
516        String Str=""
517        //control the task, and update the button text
518        if (cmpstr(ctrlName,"bkgStart") == 0)
519                Button $ctrlName,win=RT_Panel,title="Stop Updating",rename=bkgStop             
520        //      Start the updating - BkgUpdateHST() has been designated as the background task
521                CtrlBackground start
522        else
523                Button $ctrlName,win=RT_Panel,title="Start Updating",rename=bkgStart
524                NVAR elapsed=root:myGlobals:RT:elapsed
525                elapsed=0       //reset the timer
526        //      Stop the updating
527                CtrlBackground stop
528        endif
529        return(0)
530End
531
532
533// THIS IS THE BACKGROUND TASK
534//
535// simply re-reads the designated .hst file (which can be located anywhere, as long as it
536// appears as a local disk)
537// return value of 0 continues background execution
538// return value of 1 turns background task off
539//
540Function BkgUpdateHST()
541
542        WAVE data = $"root:Packages:NIST:RealTime:data"
543        Wave intw = root:Packages:NIST:RealTime:IntegersRead
544        Wave realw = root:Packages:NIST:RealTime:RealsRead
545        Wave/T textw = root:Packages:NIST:RealTime:TextRead
546
547        NVAR elapsed=root:myGlobals:RT:elapsed
548        NVAR timeout=root:myGlobals:RT:timeout
549        NVAR updateInt=root:myGlobals:RT:updateInt
550        NVAR totCounts = root:myGlobals:RT:totalCounts
551        NVAR countTime = root:myGlobals:RT:countTime
552        NVAR countRate = root:myGlobals:RT:countRate
553        NVAR monitorCounts = root:myGlobals:RT:monitorCounts
554        NVAR monitorCountRate = root:myGlobals:RT:monitorCountRate
555        SVAR title=root:myGlobals:gCurDispFile
556        SVAR sampledesc=root:myGlobals:gCurTitle
557                       
558        Variable err=0
559//      Variable t1=ticks
560        SVAR RT_fileStr=root:myGlobals:RT:RT_fileStr
561       
562        elapsed += updateInt
563//      get the new data by re-reading the datafile from the relay computer
564//      if(elapsed<timeout)
565       
566                if(WinType("SANS_Data")==0)
567                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
568                        return(1) //SANS_Data window not open
569                Endif
570                SVAR type=root:myGlobals:gDataDisplayType
571                if(cmpstr("RealTime",type)!=0)
572                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
573                        return(1)               //display not RealTime
574                Endif
575                title="Reading new data..."
576                ControlUpdate/W=SANS_Data/A
577               
578                //Copy file from ICE server
579                //ExecuteScriptText/B "\"C:\\Documents and Settings\\user\\Desktop\\ICE Test\\getdata.bat\""
580               
581                //err = ReadOrdelaHST(RT_fileStr)
582                //err = ReadHeaderAndData(RT_fileStr)
583                err = ReadRTAndData(RT_fileStr)
584                if(err==1)
585                        Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
586                        return(err)     //file not found
587                Endif
588                //Raw_to_work("RealTime")
589                // for testing only...
590//              data += abs(enoise(data))
591                //
592                MapSliderProc("reset", 0, 1)
593               
594                title=textw[0]
595                sampledesc=textw[6]
596                //sum the total counts, global variable will automatically update
597                WAVE/Z linear_data = $"root:Packages:NIST:RealTime:linear_data"
598                if(WaveExists(linear_data))
599                        totCounts = sum(linear_data, -Inf, Inf )
600                else
601                        WAVE/Z data = $"root:Packages:NIST:RealTime:data"
602                        totCounts = sum(data, -Inf, Inf )
603                endif
604                //Update other live values
605                countTime = intw[2]
606                countRate = totCounts/countTime
607                monitorCounts = realw[0]
608                monitorCountRate = monitorCounts/countTime
609               
610                //if the 1D plot is open, update this too
611                // make sure folders exist first
612                if(!DataFolderExists("root:myGlobals:Drawing"))
613                        Execute "InitializeAveragePanel()"
614                endif
615               
616                // check for the mask, generate one? Two pixels all around
617                if(WaveExists($"root:Packages:NIST:MSK:data") == 0)
618                        Print "There is no mask file loaded (WaveExists)- the data is not masked"
619                        Make/O/N=(128,128) root:Packages:NIST:MSK:data
620                        Wave mask = root:Packages:NIST:MSK:data
621                        mask[0][] = 1
622                        mask[1][] = 1
623                        mask[126][] = 1
624                        mask[127][] = 1
625                       
626                        mask[][0] = 1
627                        mask[][1] = 1
628                        mask[][126] = 1
629                        mask[][127] = 1
630                endif
631               
632                // update the 1d plot
633                if(WinType("Plot_1d")==1)               //if the 1D graph exists
634                        Panel_DoAverageButtonProc("")           
635                endif
636                ///////
637               
638//              print "Bkg task time (s) =",(ticks-t1)/60.15
639                return 0                //keep the process going
640//      else
641//              //timeout, stop the process, reset the button label
642//              elapsed=0
643//              Button $"bkgStop",win=RT_Panel,title="Start Updating",rename=bkgStart
644//              return(1)
645//      endif
646       
647End
648
649Function ReadRTAndData(fname)
650        String fname
651        //this function is for reading in RAW data only, so it will always put data in RAW folder
652        String curPath = "root:Packages:NIST:RealTime:"
653        SetDataFolder curPath           //use the full path, so it will always work
654        //Variable/G root:Packages:NIST:RAW:gIsLogScale = 0             //initial state is linear, keep this in RAW folder
655        Variable isLogScale=NumVarOrDefault("root:Packages:NIST:RealTime:gIsLogScale", 0)
656        Variable/G root:Packages:NIST:RealTime:gIsLogScale = isLogScale
657       
658        Variable refNum,integer,realval
659        String sansfname,textstr
660       
661        Make/O/N=23 $"root:Packages:NIST:RealTime:IntegersRead"
662        Make/O/N=52 $"root:Packages:NIST:RealTime:RealsRead"
663        Make/O/T/N=11 $"root:Packages:NIST:RealTime:TextRead"
664        Make/O/N=7 $"root:Packages:NIST:RealTime:LogicalsRead"
665
666       
667        Wave intw=$"root:Packages:NIST:RealTime:IntegersRead"
668        Wave realw=$"root:Packages:NIST:RealTime:RealsRead"
669        Wave/T textw=$"root:Packages:NIST:RealTime:TextRead"
670        Wave logw=$"root:Packages:NIST:RealTime:LogicalsRead"
671       
672        //***NOTE ****
673        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
674        // this read routine, after the open dialog is presented
675        // the "--read" waves end up in the correct folder, but the data does not! Why?
676        //must re-set data folder before writing data array (done below)
677       
678        //full filename and path is now passed in...
679        //actually open the file
680        Open/R refNum as fname
681        //skip first two bytes (VAX record length markers, not needed here)
682        FSetPos refNum, 2
683        //read the next 21 bytes as characters (fname)
684        FReadLine/N=21 refNum,textstr
685        textw[0]= textstr
686        //read four i*4 values  /F=3 flag, B=3 flag
687        FBinRead/F=3/B=3 refNum, integer
688        intw[0] = integer
689        //
690        FBinRead/F=3/B=3 refNum, integer
691        intw[1] = integer
692        //
693        FBinRead/F=3/B=3 refNum, integer
694        intw[2] = integer
695        //
696        FBinRead/F=3/B=3 refNum, integer
697        intw[3] = integer
698        // 6 text fields
699        FSetPos refNum,55               //will start reading at byte 56
700        FReadLine/N=20 refNum,textstr
701        textw[1]= textstr
702        FReadLine/N=3 refNum,textstr
703        textw[2]= textstr
704        FReadLine/N=11 refNum,textstr
705        textw[3]= textstr
706        FReadLine/N=1 refNum,textstr
707        textw[4]= textstr
708        FReadLine/N=8 refNum,textstr
709        textw[5]= textstr
710        FReadLine/N=60 refNum,textstr
711        textw[6]= textstr
712       
713        //3 integers
714        FSetPos refNum,174
715        FBinRead/F=3/B=3 refNum, integer
716        intw[4] = integer
717        FBinRead/F=3/B=3 refNum, integer
718        intw[5] = integer
719        FBinRead/F=3/B=3 refNum, integer
720        intw[6] = integer
721       
722        //2 integers, 3 text fields
723        FSetPos refNum,194
724        FBinRead/F=3/B=3 refNum, integer
725        intw[7] = integer
726        FBinRead/F=3/B=3 refNum, integer
727        intw[8] = integer
728        FReadLine/N=6 refNum,textstr
729        textw[7]= textstr
730        FReadLine/N=6 refNum,textstr
731        textw[8]= textstr
732        FReadLine/N=6 refNum,textstr
733        textw[9]= textstr
734       
735        //2 integers
736        FSetPos refNum,244
737        FBinRead/F=3/B=3 refNum, integer
738        intw[9] = integer
739        FBinRead/F=3/B=3 refNum, integer
740        intw[10] = integer
741       
742        //2 integers
743        FSetPos refNum,308
744        FBinRead/F=3/B=3 refNum, integer
745        intw[11] = integer
746        FBinRead/F=3/B=3 refNum, integer
747        intw[12] = integer
748       
749        //2 integers
750        FSetPos refNum,332
751        FBinRead/F=3/B=3 refNum, integer
752        intw[13] = integer
753        FBinRead/F=3/B=3 refNum, integer
754        intw[14] = integer
755       
756        //3 integers
757        FSetPos refNum,376
758        FBinRead/F=3/B=3 refNum, integer
759        intw[15] = integer
760        FBinRead/F=3/B=3 refNum, integer
761        intw[16] = integer
762        FBinRead/F=3/B=3 refNum, integer
763        intw[17] = integer
764       
765        //1 text field - the file association for transmission are the first 4 bytes
766        FSetPos refNum,404
767        FReadLine/N=42 refNum,textstr
768        textw[10]= textstr
769       
770        //1 integer
771        FSetPos refNum,458
772        FBinRead/F=3/B=3 refNum, integer
773        intw[18] = integer
774       
775        //4 integers
776        FSetPos refNum,478
777        FBinRead/F=3/B=3 refNum, integer
778        intw[19] = integer
779        FBinRead/F=3/B=3 refNum, integer
780        intw[20] = integer
781        FBinRead/F=3/B=3 refNum, integer
782        intw[21] = integer
783        FBinRead/F=3/B=3 refNum, integer
784        intw[22] = integer
785       
786        //Get Logicals 
787        //Read logicals as int - ICE is writing integers here
788        FSetPos refNum,304
789        FBinRead/F=3/B=3 refNum, integer
790        logw[0] = integer
791        FSetPos refNum,316
792        FBinRead/F=3/B=3 refNum, integer
793        logw[1] = integer       
794        FSetPos refNum,340
795        FBinRead/F=3/B=3 refNum, integer
796        logw[2] = integer
797        FSetPos refNum,344
798        FBinRead/F=3/B=3 refNum, integer
799        logw[3] = integer               
800        FSetPos refNum,446
801        FBinRead/F=3/B=3 refNum, integer
802        logw[4] = integer
803        FSetPos refNum,462
804        FBinRead/F=3/B=3 refNum, integer
805        logw[5] = integer
806        FSetPos refNum,466
807        FBinRead/F=3/B=3 refNum, integer
808        logw[6] = integer               
809
810       
811        Close refNum
812       
813        //now get all of the reals
814        //
815        //Do all the GBLoadWaves at the end
816        //
817        //FBinRead Cannot handle 32 bit VAX floating point
818        //GBLoadWave, however, can properly read it
819        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
820        String strToExecute
821        //append "/S=offset/U=numofreals" to control the read
822        // then append fname to give the full file path
823        // then execute
824       
825        Variable a=0,b=0
826       
827        SetDataFolder curPath
828       
829        // 4 R*4 values
830        strToExecute = GBLoadStr + "/S=39/U=4" + "\"" + fname + "\""
831        Execute strToExecute
832        Wave w=$"root:Packages:NIST:RealTime:tempGBWave0"
833        b=4     //num of reals read
834        realw[a,a+b-1] = w[p-a]
835        a+=b
836       
837        // 4 R*4 values
838        SetDataFolder curPath
839        strToExecute = GBLoadStr + "/S=158/U=4" + "\"" + fname + "\""
840        Execute strToExecute
841        b=4     
842        realw[a,a+b-1] = w[p-a]
843        a+=b
844
845///////////
846        // 2 R*4 values
847        SetDataFolder curPath
848        strToExecute = GBLoadStr + "/S=186/U=2" + "\"" + fname + "\""
849        Execute strToExecute
850        b=2     
851        realw[a,a+b-1] = w[p-a]
852        a+=b
853
854        // 6 R*4 values
855        SetDataFolder curPath
856        strToExecute = GBLoadStr + "/S=220/U=6" + "\"" + fname + "\""
857        Execute strToExecute
858        b=6     
859        realw[a,a+b-1] = w[p-a]
860        a+=b
861       
862        // 13 R*4 values
863        SetDataFolder curPath
864        strToExecute = GBLoadStr + "/S=252/U=13" + "\"" + fname + "\""
865        Execute strToExecute
866        b=13
867        realw[a,a+b-1] = w[p-a]
868        a+=b
869       
870        // 3 R*4 values
871        SetDataFolder curPath
872        strToExecute = GBLoadStr + "/S=320/U=3" + "\"" + fname + "\""
873        Execute strToExecute
874        b=3     
875        realw[a,a+b-1] = w[p-a]
876        a+=b
877       
878        // 7 R*4 values
879        SetDataFolder curPath
880        strToExecute = GBLoadStr + "/S=348/U=7" + "\"" + fname + "\""
881        Execute strToExecute
882        b=7
883        realw[a,a+b-1] = w[p-a]
884        a+=b
885       
886        // 4 R*4 values
887        SetDataFolder curPath
888        strToExecute = GBLoadStr + "/S=388/U=4" + "\"" + fname + "\""
889        Execute strToExecute
890        b=4     
891        realw[a,a+b-1] = w[p-a]
892        a+=b
893       
894        // 2 R*4 values
895        SetDataFolder curPath
896        strToExecute = GBLoadStr + "/S=450/U=2" + "\"" + fname + "\""
897        Execute strToExecute
898        b=2
899        realw[a,a+b-1] = w[p-a]
900        a+=b
901       
902        // 2 R*4 values
903        SetDataFolder curPath
904        strToExecute = GBLoadStr + "/S=470/U=2" + "\"" + fname + "\""
905        Execute strToExecute
906        b=2
907        realw[a,a+b-1] = w[p-a]
908        a+=b
909       
910        // 5 R*4 values
911        SetDataFolder curPath
912        strToExecute = GBLoadStr + "/S=494/U=5" + "\"" + fname + "\""
913        Execute strToExecute
914        b=5     
915        realw[a,a+b-1] = w[p-a]
916       
917        //if the binary VAX data ws transferred to a MAC, all is OK
918        //if the data was trasnferred to an Intel machine (IBM), all the real values must be
919        //divided by 4 to get the correct floating point values
920        // I can't find any combination of settings in GBLoadWave or FBinRead to read data in correctly
921        // on an Intel machine.
922        //With the corrected version of GBLoadWave XOP (v. 1.43 or higher) Mac and PC both read
923        //VAX reals correctly, and no checking is necessary 12 APR 99
924        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
925                //do nothing
926        //else
927                //either Windows or Windows NT
928                //realw /= 4
929        //endif
930       
931        SetDataFolder curPath
932        //read in the data
933        strToExecute = "GBLoadWave/O/N=tempGBwave/B/T={16,2}/S=514/Q" + "\"" + fname + "\""
934        Execute strToExecute
935
936        SetDataFolder curPath           //use the full path, so it will always work
937       
938        Make/O/N=16384 $"root:Packages:NIST:RealTime:data"
939        WAVE data=$"root:Packages:NIST:RealTime:data"
940        SkipAndDecompressVAX(w,data)
941        Redimension/N=(128,128) data                    //NIST raw data is 128x128 - do not generalize
942       
943        Duplicate/O data,$"root:Packages:NIST:RealTime:linear_data"
944        WAVE lin_data=$"root:Packages:NIST:RealTime:linear_data"
945        if(isLogScale)
946                data=log(lin_data)
947        else
948                data=lin_data
949        Endif
950       
951        //keep a string with the filename in the RAW folder
952        String/G root:Packages:NIST:RealTime:fileList = textw[0]
953       
954        //set the globals to the detector dimensions (pixels)
955        Variable/G root:myGlobals:gNPixelsX=128         //default for Ordela data (also set in Initialize/NCNR_Utils.ipf)
956        Variable/G root:myGlobals:gNPixelsY=128
957//      if(cmpstr(textW[9],"ILL   ")==0)                //override if OLD Cerca data
958//              Variable/G root:myGlobals:gNPixelsX=64
959//              Variable/G root:myGlobals:gNPixelsY=64
960//      endif
961       
962        //clean up - get rid of w = $"root:Packages:NIST:RAW:tempGBWave0"
963        KillWaves/Z w
964       
965        //return the data folder to root
966        SetDataFolder root:
967       
968        Return 0
969
970End
Note: See TracBrowser for help on using the repository browser.