source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/NCNR_DataReadWrite.ipf @ 557

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

Added function to the SANSBeta menu for reduction to be able to re-write the filename to the header, correctly accounting for possible blank spaces caused by a prefix of less than 5 characters. VAX puts the spaces at the beginning of the field, ICE puts them at the end. As a result, the unique file suffix is not at the correct byte location.

ICE will be notified of the necessary change.

File size: 68.8 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion = 6.0
4
5//**************************
6//
7// Vers. 1.2 092101
8// Vers. 5.0 29MAR07 - branched from main reduction to split out facility
9//                     specific calls
10//
11// functions for reading raw data files from the VAX
12// - RAW data files are read into the RAW folder - integer data from the detector
13//   is decompressed and given the proper orientation
14// - header information is placed into real,integer, or text waves in the order they appear
15//   in the file header
16//
17// Work data (DIV File) is read into the DIV folder
18//
19//*****************************
20
21//simple, main entry procedure that will load a RAW sans data file (not a work file)
22//into the RAW dataFolder. It is up to the calling procedure to display the file
23//
24// called by MainPanel.ipf and ProtocolAsPanel.ipf
25//
26Function LoadRawSANSData(msgStr)
27        String msgStr
28
29        String filename=""
30
31        //each routine is responsible for checking the current (displayed) data folder
32        //selecting it, and returning to root when done
33        PathInfo/S catPathName          //should set the next dialog to the proper path...
34        //get the filename, then read it in
35        filename = PromptForPath(msgStr)                //in SANS_Utils.ipf
36        //check for cancel from dialog
37        if(strlen(filename)==0)
38                //user cancelled, abort
39                SetDataFolder root:
40                DoAlert 0, "No file selected, action aborted"
41                return(1)
42        Endif
43        //Print  "GetFileNameFromPath(filename) = " +  GetFileNameFromPathNoSemi(filename)
44        ReadHeaderAndData(filename)     //this is the full Path+file
45
46///***** done by a call to UpdateDisplayInformation()
47//      //the calling macro must change the display type
48//      String/G root:myGlobals:gDataDisplayType="RAW"          //displayed data type is raw
49//     
50//      //data is displayed here
51//      fRawWindowHook()
52       
53        Return(0)
54End
55
56
57//function that does the guts of reading the binary data file
58//fname is the full path:name;vers required to open the file
59//VAX record markers are skipped as needed
60//VAX data as read in is in compressed I*2 format, and is decompressed
61//immediately after being read in. The final root:Packages:NIST:RAW:data wave is the real
62//neutron counts and can be directly operated on
63//
64// header information is put into three waves: integersRead, realsRead, and textRead
65// logicals in the header are currently skipped, since they are no use in the
66// data reduction process.
67//
68// The output is the three R/T/I waves that are filled at least with minimal values
69// and the detector data loaded into an array named "data"
70//
71// see documentation for the expected information in each element of the R/T/I waves
72// and the minimum set of information. These waves can be increased in length so that
73// more information can be accessed as needed (propagating changes...)
74//
75// called by multiple .ipfs (when the file name is known)
76//
77Function ReadHeaderAndData(fname)
78        String fname
79        //this function is for reading in RAW data only, so it will always put data in RAW folder
80        String curPath = "root:Packages:NIST:RAW:"
81        SetDataFolder curPath           //use the full path, so it will always work
82        Variable/G root:Packages:NIST:RAW:gIsLogScale = 0               //initial state is linear, keep this in RAW folder
83       
84        Variable refNum,integer,realval
85        String sansfname,textstr
86       
87        Make/O/N=23 $"root:Packages:NIST:RAW:IntegersRead"
88        Make/O/N=52 $"root:Packages:NIST:RAW:RealsRead"
89        Make/O/T/N=11 $"root:Packages:NIST:RAW:TextRead"
90        Make/O/N=7 $"root:Packages:NIST:RAW:LogicalsRead"
91       
92        Wave intw=$"root:Packages:NIST:RAW:IntegersRead"
93        Wave realw=$"root:Packages:NIST:RAW:RealsRead"
94        Wave/T textw=$"root:Packages:NIST:RAW:TextRead"
95        Wave logw=$"root:Packages:NIST:RAW:LogicalsRead"
96       
97        //***NOTE ****
98        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
99        // this read routine, after the open dialog is presented
100        // the "--read" waves end up in the correct folder, but the data does not! Why?
101        //must re-set data folder before writing data array (done below)
102       
103        //full filename and path is now passed in...
104        //actually open the file
105        Open/R refNum as fname
106        //skip first two bytes (VAX record length markers, not needed here)
107        FSetPos refNum, 2
108        //read the next 21 bytes as characters (fname)
109        FReadLine/N=21 refNum,textstr
110        textw[0]= textstr
111        //read four i*4 values  /F=3 flag, B=3 flag
112        FBinRead/F=3/B=3 refNum, integer
113        intw[0] = integer
114        //
115        FBinRead/F=3/B=3 refNum, integer
116        intw[1] = integer
117        //
118        FBinRead/F=3/B=3 refNum, integer
119        intw[2] = integer
120        //
121        FBinRead/F=3/B=3 refNum, integer
122        intw[3] = integer
123        // 6 text fields
124        FSetPos refNum,55               //will start reading at byte 56
125        FReadLine/N=20 refNum,textstr
126        textw[1]= textstr
127        FReadLine/N=3 refNum,textstr
128        textw[2]= textstr
129        FReadLine/N=11 refNum,textstr
130        textw[3]= textstr
131        FReadLine/N=1 refNum,textstr
132        textw[4]= textstr
133        FReadLine/N=8 refNum,textstr
134        textw[5]= textstr
135        FReadLine/N=60 refNum,textstr
136        textw[6]= textstr
137       
138        //3 integers
139        FSetPos refNum,174
140        FBinRead/F=3/B=3 refNum, integer
141        intw[4] = integer
142        FBinRead/F=3/B=3 refNum, integer
143        intw[5] = integer
144        FBinRead/F=3/B=3 refNum, integer
145        intw[6] = integer
146       
147        //2 integers, 3 text fields
148        FSetPos refNum,194
149        FBinRead/F=3/B=3 refNum, integer
150        intw[7] = integer
151        FBinRead/F=3/B=3 refNum, integer
152        intw[8] = integer
153        FReadLine/N=6 refNum,textstr
154        textw[7]= textstr
155        FReadLine/N=6 refNum,textstr
156        textw[8]= textstr
157        FReadLine/N=6 refNum,textstr
158        textw[9]= textstr
159       
160        //2 integers
161        FSetPos refNum,244
162        FBinRead/F=3/B=3 refNum, integer
163        intw[9] = integer
164        FBinRead/F=3/B=3 refNum, integer
165        intw[10] = integer
166       
167       
168        //2 integers
169        FSetPos refNum,308
170        FBinRead/F=3/B=3 refNum, integer
171        intw[11] = integer
172        FBinRead/F=3/B=3 refNum, integer
173        intw[12] = integer
174       
175        //2 integers
176        FSetPos refNum,332
177        FBinRead/F=3/B=3 refNum, integer
178        intw[13] = integer
179        FBinRead/F=3/B=3 refNum, integer
180        intw[14] = integer
181       
182        //3 integers
183        FSetPos refNum,376
184        FBinRead/F=3/B=3 refNum, integer
185        intw[15] = integer
186        FBinRead/F=3/B=3 refNum, integer
187        intw[16] = integer
188        FBinRead/F=3/B=3 refNum, integer
189        intw[17] = integer
190       
191        //1 text field - the file association for transmission are the first 4 bytes
192        FSetPos refNum,404
193        FReadLine/N=42 refNum,textstr
194        textw[10]= textstr
195       
196        //1 integer
197        FSetPos refNum,458
198        FBinRead/F=3/B=3 refNum, integer
199        intw[18] = integer
200       
201        //4 integers
202        FSetPos refNum,478
203        FBinRead/F=3/B=3 refNum, integer
204        intw[19] = integer
205        FBinRead/F=3/B=3 refNum, integer
206        intw[20] = integer
207        FBinRead/F=3/B=3 refNum, integer
208        intw[21] = integer
209        FBinRead/F=3/B=3 refNum, integer
210        intw[22] = integer
211
212        //Get Logicals 
213        //Read logicals as int - ICE is writing integers here
214        FSetPos refNum,304
215        FBinRead/F=3/B=3 refNum, integer
216        logw[0] = integer
217        FSetPos refNum,316
218        FBinRead/F=3/B=3 refNum, integer
219        logw[1] = integer       
220        FSetPos refNum,340
221        FBinRead/F=3/B=3 refNum, integer
222        logw[2] = integer
223        FSetPos refNum,344
224        FBinRead/F=3/B=3 refNum, integer
225        logw[3] = integer               
226        FSetPos refNum,446
227        FBinRead/F=3/B=3 refNum, integer
228        logw[4] = integer
229        FSetPos refNum,462
230        FBinRead/F=3/B=3 refNum, integer
231        logw[5] = integer
232        FSetPos refNum,466
233        FBinRead/F=3/B=3 refNum, integer
234        logw[6] = integer               
235
236        Close refNum
237       
238        //now get all of the reals
239        //
240        //Do all the GBLoadWaves at the end
241        //
242        //FBinRead Cannot handle 32 bit VAX floating point
243        //GBLoadWave, however, can properly read it
244        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
245        String strToExecute
246        //append "/S=offset/U=numofreals" to control the read
247        // then append fname to give the full file path
248        // then execute
249       
250        Variable a=0,b=0
251       
252        SetDataFolder curPath
253       
254        // 4 R*4 values
255        strToExecute = GBLoadStr + "/S=39/U=4" + "\"" + fname + "\""
256        Execute strToExecute
257        Wave w=$"root:Packages:NIST:RAW:tempGBWave0"
258        b=4     //num of reals read
259        realw[a,a+b-1] = w[p-a]
260        a+=b
261       
262        // 4 R*4 values
263        SetDataFolder curPath
264        strToExecute = GBLoadStr + "/S=158/U=4" + "\"" + fname + "\""
265        Execute strToExecute
266        b=4     
267        realw[a,a+b-1] = w[p-a]
268        a+=b
269
270///////////
271        // 2 R*4 values
272        SetDataFolder curPath
273        strToExecute = GBLoadStr + "/S=186/U=2" + "\"" + fname + "\""
274        Execute strToExecute
275        b=2     
276        realw[a,a+b-1] = w[p-a]
277        a+=b
278
279        // 6 R*4 values
280        SetDataFolder curPath
281        strToExecute = GBLoadStr + "/S=220/U=6" + "\"" + fname + "\""
282        Execute strToExecute
283        b=6     
284        realw[a,a+b-1] = w[p-a]
285        a+=b
286       
287        // 13 R*4 values
288        SetDataFolder curPath
289        strToExecute = GBLoadStr + "/S=252/U=13" + "\"" + fname + "\""
290        Execute strToExecute
291        b=13
292        realw[a,a+b-1] = w[p-a]
293        a+=b
294       
295        // 3 R*4 values
296        SetDataFolder curPath
297        strToExecute = GBLoadStr + "/S=320/U=3" + "\"" + fname + "\""
298        Execute strToExecute
299        b=3     
300        realw[a,a+b-1] = w[p-a]
301        a+=b
302       
303        // 7 R*4 values
304        SetDataFolder curPath
305        strToExecute = GBLoadStr + "/S=348/U=7" + "\"" + fname + "\""
306        Execute strToExecute
307        b=7
308        realw[a,a+b-1] = w[p-a]
309        a+=b
310       
311        // 4 R*4 values
312        SetDataFolder curPath
313        strToExecute = GBLoadStr + "/S=388/U=4" + "\"" + fname + "\""
314        Execute strToExecute
315        b=4     
316        realw[a,a+b-1] = w[p-a]
317        a+=b
318       
319        // 2 R*4 values
320        SetDataFolder curPath
321        strToExecute = GBLoadStr + "/S=450/U=2" + "\"" + fname + "\""
322        Execute strToExecute
323        b=2
324        realw[a,a+b-1] = w[p-a]
325        a+=b
326       
327        // 2 R*4 values
328        SetDataFolder curPath
329        strToExecute = GBLoadStr + "/S=470/U=2" + "\"" + fname + "\""
330        Execute strToExecute
331        b=2
332        realw[a,a+b-1] = w[p-a]
333        a+=b
334       
335        // 5 R*4 values
336        SetDataFolder curPath
337        strToExecute = GBLoadStr + "/S=494/U=5" + "\"" + fname + "\""
338        Execute strToExecute
339        b=5     
340        realw[a,a+b-1] = w[p-a]
341       
342        //if the binary VAX data ws transferred to a MAC, all is OK
343        //if the data was trasnferred to an Intel machine (IBM), all the real values must be
344        //divided by 4 to get the correct floating point values
345        // I can't find any combination of settings in GBLoadWave or FBinRead to read data in correctly
346        // on an Intel machine.
347        //With the corrected version of GBLoadWave XOP (v. 1.43 or higher) Mac and PC both read
348        //VAX reals correctly, and no checking is necessary 12 APR 99
349        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
350                //do nothing
351        //else
352                //either Windows or Windows NT
353                //realw /= 4
354        //endif
355       
356        SetDataFolder curPath
357        //read in the data
358        strToExecute = "GBLoadWave/O/N=tempGBwave/B/T={16,2}/S=514/Q" + "\"" + fname + "\""
359        Execute strToExecute
360
361        SetDataFolder curPath           //use the full path, so it will always work
362       
363        Make/O/N=16384 $"root:Packages:NIST:RAW:data"
364        WAVE data=$"root:Packages:NIST:RAW:data"
365        SkipAndDecompressVAX(w,data)
366        Redimension/N=(128,128) data                    //NIST raw data is 128x128 - do not generalize
367       
368        //keep a string with the filename in the RAW folder
369        String/G root:Packages:NIST:RAW:fileList = textw[0]
370       
371        //set the globals to the detector dimensions (pixels)
372        Variable/G root:myGlobals:gNPixelsX=128         //default for Ordela data (also set in Initialize/NCNR_Utils.ipf)
373        Variable/G root:myGlobals:gNPixelsY=128
374//      if(cmpstr(textW[9],"ILL   ")==0)                //override if OLD Cerca data
375//              Variable/G root:myGlobals:gNPixelsX=64
376//              Variable/G root:myGlobals:gNPixelsY=64
377//      endif
378       
379        //clean up - get rid of w = $"root:Packages:NIST:RAW:tempGBWave0"
380//      KillWaves/Z w
381       
382        //return the data folder to root
383        SetDataFolder root:
384       
385        Return 0
386
387End
388
389
390//function to take the I*2 data that was read in, in VAX format
391//where the integers are "normal", but there are 2-byte record markers
392//sprinkled evenly through the data
393//there are skipped, leaving 128x128=16384 data values
394//the input array (in) is larger than 16384
395//(out) is 128x128 data (single precision) as defined in ReadHeaderAndData()
396//
397// local function to post-process compressed VAX binary data
398//
399//
400Function SkipAndDecompressVAX(in,out)
401        Wave in,out
402       
403        Variable skip,ii
404
405        ii=0
406        skip=0
407        do
408                if(mod(ii+skip,1022)==0)
409                        skip+=1
410                endif
411                out[ii] = Decompress(in[ii+skip])
412                ii+=1
413        while(ii<16384)
414        return(0)
415End
416
417//decompresses each I*2 data value to its real I*4 value
418//using the decompression routine written by Jim Ryhne, many moons ago
419//
420// the compression routine (not shown here, contained in the VAX fortran RW_DATAFILE.FOR) maps I4 to I2 values.
421// (back in the days where disk space *really* mattered). the I4toI2 function spit out:
422// I4toI2 = I4                                                          when I4 in [0,32767]
423// I4toI2 = -777                                                        when I4 in [2,767,000,...]
424// I4toI2 mapped to -13277 to -32768    otherwise
425//
426// the mapped values [-776,-1] and [-13276,-778] are not used.
427// in this compression scheme, only 4 significant digits are retained (to allow room for the exponent)
428// technically, the maximum value should be 2,768,499 since this maps to -32768. But this is of
429// little consequence. If you have individual pixel values on the detector that are that large, you need
430// to re-think your experiment.
431//
432// local function to post-process compressed VAX binary data
433//
434//
435Function Decompress(val)
436        Variable val
437
438        Variable i4,npw,ipw,ib,nd
439
440        ib=10
441        nd=4
442        ipw=ib^nd
443        i4=val
444
445        if (i4 <= -ipw)
446                npw=trunc(-i4/ipw)
447                i4=mod(-i4,ipw)*(ib^npw)
448                return i4
449        else
450                return i4
451        endif
452End
453
454//****************
455//main entry procedure for reading a "WORK.DIV" file
456//displays a quick image of the  file, to check that it's correct
457//data is deposited in root:Packages:NIST:DIV data folder
458//
459// local, currently unused
460//
461//
462Proc ReadWork_DIV()
463//      Silent 1
464       
465        String fname = PromptForPath("Select detector sensitivity file")
466        ReadHeaderAndWork("DIV",fname)          //puts what is read in work.div
467       
468        String waveStr = "root:Packages:NIST:DIV:data"
469//      NewImage/F/K=1/S=2 $waveStr             //this is an experimental IGOR operation
470//      ModifyImage '' ctab= {*,*,YellowHot,0}
471        //Display;AppendImage $waveStr
472       
473        //change the title string to WORK.DIV, rather than PLEXnnn_TST_asdfa garbage
474//      String/G root:Packages:NIST:DIV:fileList = "WORK.DIV"
475        ChangeDisplay("DIV")
476       
477        SetDataFolder root:             //(redundant)
478//      Silent 0
479End
480
481
482//this function is the guts of reading a binary VAX file of real (4-byte) values
483// (i.e. a WORK.aaa file)
484// work files have the same header structure as RAW SANS data, just with
485//different data (real, rather than compressed integer data)
486//
487//************
488//this routine incorrectly reads in several data values where the VAX record
489//marker splits the 4-byte real (at alternating record markers)
490//this error seems to not be severe, but shoud be corrected (at great pain)
491//************
492//
493// called from ProtocolAsPanel.ipf
494//
495//
496Function ReadHeaderAndWork(type,fname)
497        String type,fname
498       
499        //type is the desired folder to read the workfile to
500        //this data will NOT be automatically displayed gDataDisplayType is unchanged
501
502//      SVAR cur_folder=root:myGlobals:gDataDisplayType
503        String cur_folder = type
504        String curPath = "root:Packages:NIST:"+cur_folder
505        SetDataFolder curPath           //use the full path, so it will always work
506       
507        Variable refNum,integer,realval
508        String sansfname,textstr
509        Variable/G $(curPath + ":gIsLogScale") = 0              //initial state is linear, keep this in DIV folder
510       
511        Make/O/N=23 $(curPath + ":IntegersRead")
512        Make/O/N=52 $(curPath + ":RealsRead")
513        Make/O/T/N=11 $(curPath + ":TextRead")
514       
515        WAVE intw=$(curPath + ":IntegersRead")
516        WAVE realw=$(curPath + ":RealsRead")
517        WAVE/T textw=$(curPath + ":TextRead")
518       
519        //***NOTE ****
520        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
521        // this read routine, after the open dialog is presented
522        // the "--read" waves end up in the correct folder, but the data does not! Why?
523        //must re-set data folder before writing data array (done below)
524       
525        SetDataFolder curPath
526       
527        //actually open the file
528        Open/R refNum as fname
529        //skip first two bytes
530        FSetPos refNum, 2
531        //read the next 21 bytes as characters (fname)
532        FReadLine/N=21 refNum,textstr
533        textw[0]= textstr
534        //read four i*4 values  /F=3 flag, B=3 flag
535        FBinRead/F=3/B=3 refNum, integer
536        intw[0] = integer
537        //
538        FBinRead/F=3/B=3 refNum, integer
539        intw[1] = integer
540        //
541        FBinRead/F=3/B=3 refNum, integer
542        intw[2] = integer
543        //
544        FBinRead/F=3/B=3 refNum, integer
545        intw[3] = integer
546        // 6 text fields
547        FSetPos refNum,55               //will start reading at byte 56
548        FReadLine/N=20 refNum,textstr
549        textw[1]= textstr
550        FReadLine/N=3 refNum,textstr
551        textw[2]= textstr
552        FReadLine/N=11 refNum,textstr
553        textw[3]= textstr
554        FReadLine/N=1 refNum,textstr
555        textw[4]= textstr
556        FReadLine/N=8 refNum,textstr
557        textw[5]= textstr
558        FReadLine/N=60 refNum,textstr
559        textw[6]= textstr
560       
561        //3 integers
562        FSetPos refNum,174
563        FBinRead/F=3/B=3 refNum, integer
564        intw[4] = integer
565        FBinRead/F=3/B=3 refNum, integer
566        intw[5] = integer
567        FBinRead/F=3/B=3 refNum, integer
568        intw[6] = integer
569       
570        //2 integers, 3 text fields
571        FSetPos refNum,194
572        FBinRead/F=3/B=3 refNum, integer
573        intw[7] = integer
574        FBinRead/F=3/B=3 refNum, integer
575        intw[8] = integer
576        FReadLine/N=6 refNum,textstr
577        textw[7]= textstr
578        FReadLine/N=6 refNum,textstr
579        textw[8]= textstr
580        FReadLine/N=6 refNum,textstr
581        textw[9]= textstr
582       
583        //2 integers
584        FSetPos refNum,244
585        FBinRead/F=3/B=3 refNum, integer
586        intw[9] = integer
587        FBinRead/F=3/B=3 refNum, integer
588        intw[10] = integer
589       
590        //2 integers
591        FSetPos refNum,308
592        FBinRead/F=3/B=3 refNum, integer
593        intw[11] = integer
594        FBinRead/F=3/B=3 refNum, integer
595        intw[12] = integer
596       
597        //2 integers
598        FSetPos refNum,332
599        FBinRead/F=3/B=3 refNum, integer
600        intw[13] = integer
601        FBinRead/F=3/B=3 refNum, integer
602        intw[14] = integer
603       
604        //3 integers
605        FSetPos refNum,376
606        FBinRead/F=3/B=3 refNum, integer
607        intw[15] = integer
608        FBinRead/F=3/B=3 refNum, integer
609        intw[16] = integer
610        FBinRead/F=3/B=3 refNum, integer
611        intw[17] = integer
612       
613        //1 text field - the file association for transmission are the first 4 bytes
614        FSetPos refNum,404
615        FReadLine/N=42 refNum,textstr
616        textw[10]= textstr
617       
618        //1 integer
619        FSetPos refNum,458
620        FBinRead/F=3/B=3 refNum, integer
621        intw[18] = integer
622       
623        //4 integers
624        FSetPos refNum,478
625        FBinRead/F=3/B=3 refNum, integer
626        intw[19] = integer
627        FBinRead/F=3/B=3 refNum, integer
628        intw[20] = integer
629        FBinRead/F=3/B=3 refNum, integer
630        intw[21] = integer
631        FBinRead/F=3/B=3 refNum, integer
632        intw[22] = integer
633       
634        Close refNum
635       
636        //now get all of the reals
637        //
638        //Do all the GBLoadWaves at the end
639        //
640        //FBinRead Cannot handle 32 bit VAX floating point
641        //GBLoadWave, however, can properly read it
642        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
643        String strToExecute
644        //append "/S=offset/U=numofreals" to control the read
645        // then append fname to give the full file path
646        // then execute
647       
648        Variable a=0,b=0
649       
650        SetDataFolder curPath
651        // 4 R*4 values
652        strToExecute = GBLoadStr + "/S=39/U=4" + "\"" + fname + "\""
653        Execute strToExecute
654       
655        SetDataFolder curPath
656        Wave w=$(curPath + ":tempGBWave0")
657        b=4     //num of reals read
658        realw[a,a+b-1] = w[p-a]
659        a+=b
660       
661        // 4 R*4 values
662        SetDataFolder curPath
663        strToExecute = GBLoadStr + "/S=158/U=4" + "\"" + fname + "\""
664        Execute strToExecute
665        b=4     
666        realw[a,a+b-1] = w[p-a]
667        a+=b
668
669///////////
670        // 2 R*4 values
671        SetDataFolder curPath
672        strToExecute = GBLoadStr + "/S=186/U=2" + "\"" + fname + "\""
673        Execute strToExecute
674        b=2     
675        realw[a,a+b-1] = w[p-a]
676        a+=b
677
678        // 6 R*4 values
679        SetDataFolder curPath
680        strToExecute = GBLoadStr + "/S=220/U=6" + "\"" + fname + "\""
681        Execute strToExecute
682        b=6     
683        realw[a,a+b-1] = w[p-a]
684        a+=b
685       
686        // 13 R*4 values
687        SetDataFolder curPath
688        strToExecute = GBLoadStr + "/S=252/U=13" + "\"" + fname + "\""
689        Execute strToExecute
690        b=13
691        realw[a,a+b-1] = w[p-a]
692        a+=b
693       
694        // 3 R*4 values
695        SetDataFolder curPath
696        strToExecute = GBLoadStr + "/S=320/U=3" + "\"" + fname + "\""
697        Execute strToExecute
698        b=3     
699        realw[a,a+b-1] = w[p-a]
700        a+=b
701       
702        // 7 R*4 values
703        SetDataFolder curPath
704        strToExecute = GBLoadStr + "/S=348/U=7" + "\"" + fname + "\""
705        Execute strToExecute
706        b=7
707        realw[a,a+b-1] = w[p-a]
708        a+=b
709       
710        // 4 R*4 values
711        SetDataFolder curPath
712        strToExecute = GBLoadStr + "/S=388/U=4" + "\"" + fname + "\""
713        Execute strToExecute
714        b=4     
715        realw[a,a+b-1] = w[p-a]
716        a+=b
717       
718        // 2 R*4 values
719        SetDataFolder curPath
720        strToExecute = GBLoadStr + "/S=450/U=2" + "\"" + fname + "\""
721        Execute strToExecute
722        b=2
723        realw[a,a+b-1] = w[p-a]
724        a+=b
725       
726        // 2 R*4 values
727        SetDataFolder curPath
728        strToExecute = GBLoadStr + "/S=470/U=2" + "\"" + fname + "\""
729        Execute strToExecute
730        b=2
731        realw[a,a+b-1] = w[p-a]
732        a+=b
733       
734        // 5 R*4 values
735        SetDataFolder curPath
736        strToExecute = GBLoadStr + "/S=494/U=5" + "\"" + fname + "\""
737        Execute strToExecute
738        b=5     
739        realw[a,a+b-1] = w[p-a]
740       
741        //if the binary VAX data ws transferred to a MAC, all is OK
742        //if the data was trasnferred to an Intel machine (IBM), all the real values must be
743        //divided by 4 to get the correct floating point values
744        // I can't find any combination of settings in GBLoadWave or FBinRead to read data in correctly
745        // on an Intel machine.
746        //With the corrected version of GBLoadWave XOP (v. 1.43 or higher) Mac and PC both read
747        //VAX reals correctly, and no checking is necessary 12 APR 99
748        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
749                //do nothing
750        //else
751                //either Windows or Windows NT
752                //realw /= 4
753        //endif
754       
755        //read in the data
756         GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
757
758        curPath = "root:Packages:NIST:"+cur_folder
759        SetDataFolder curPath           //use the full path, so it will always work
760       
761        Make/O/N=16384 $(curPath + ":data")
762        WAVE data = $(curPath + ":data")
763       
764        Variable skip,ii,offset
765       
766        //read in a total of 16384 values (ii)
767        //as follows :
768        // skip first 2 bytes
769        // skip 512 byte header
770        // skip first 2 bytes of data
771        //(read 511 reals, skip 2b, 510 reals, skip 2b) -16 times = 16336 values
772        // read the final 48 values in seperately to avoid EOF error
773       
774        /////////////
775        SetDataFolder curPath
776        skip = 0
777        ii=0
778        offset = 514 +2
779        a=0
780        do
781                SetDataFolder curPath
782               
783                strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=511" + "\"" + fname + "\""
784                Execute strToExecute
785                //Print strToExecute
786                b=511
787                data[a,a+b-1] = w[p-a]
788                a+=b
789               
790                offset += 511*4 +2
791               
792                strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=510" + "\"" + fname + "\""
793                SetDataFolder curPath
794                Execute strToExecute
795                //Print strToExecute
796                b=510
797                data[a,a+b-1] = w[p-a]
798                a+=b
799               
800                offset += 510*4 +2
801               
802                ii+=1
803                //Print "inside do, data[2] =",data[2]
804                //Print "inside do, tempGBwave0[0] = ",w[0]
805        while(ii<16)
806       
807        // 16336 values have been read in --
808        //read in last 64 values
809        strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=48" + "\"" + fname + "\""
810       
811        SetDataFolder curPath
812        Execute strToExecute
813        b=48
814        data[a,a+b-1] = w[p-a]
815        a+=b
816//
817/// done reading in raw data
818//
819        //Print "in workdatareader , data = ", data[1][1]
820
821        Redimension/n=(128,128) data
822       
823        //clean up - get rid of w = $"tempGBWave0"
824        KillWaves w
825       
826        //divide the FP data by 4 if read from a PC (not since GBLoadWave update)
827        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
828                //do nothing
829        //else
830                //either Windows or Windows NT
831                //data /= 4
832        //endif
833       
834        //keep a string with the filename in the DIV folder
835        String/G $(curPath + ":fileList") = textw[0]
836       
837        //return the data folder to root
838        SetDataFolder root:
839       
840        Return(0)
841End
842
843/////   ASC FORMAT READER  //////
844/////   FOR WORKFILE MATH PANEL //////
845
846//function to read in the ASC output of SANS reduction
847// currently the file has 20 header lines, followed by a single column
848// of 16384 values, Data is written by row, starting with Y=1 and X=(1->128)
849//
850//returns 0 if read was ok
851//returns 1 if there was an error
852//
853// called by WorkFileUtils.ipf
854//
855Function ReadASCData(fname,destPath)
856        String fname, destPath
857        //this function is for reading in ASCII data so put data in user-specified folder
858        SetDataFolder "root:Packages:NIST:"+destPath
859
860        NVAR pixelsX = root:myGlobals:gNPixelsX
861        NVAR pixelsY = root:myGlobals:gNPixelsY
862        Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20
863        String str=""
864        //data is initially linear scale
865        Variable/G :gIsLogScale=0
866        Make/O/T/N=(numHdrLines) hdrLines
867        Make/O/D/N=(pixelsX*pixelsY) data                       //,linear_data
868       
869        //full filename and path is now passed in...
870        //actually open the file
871//      SetDataFolder destPath
872        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
873        if(refnum==0)           //FNF error, get out
874                DoAlert 0,"Could not find file: "+fname
875                Close/A
876                SetDataFolder root:
877                return(1)
878        endif
879        if(V_flag!=0)
880                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
881                Close/A
882                SetDataFolder root:
883                return(1)
884        Endif
885        //
886        for(ii=0;ii<numHdrLines;ii+=1)          //read (or skip) 18 header lines
887                FReadLine refnum,str
888                hdrLines[ii]=str
889        endfor
890        //     
891        Close refnum
892       
893//      SetDataFolder destPath
894        LoadWave/Q/G/D/N=temp fName
895        Wave/Z temp0=temp0
896        data=temp0
897        Redimension/N=(pixelsX,pixelsY) data            //,linear_data
898       
899        //linear_data = data
900       
901        KillWaves/Z temp0
902       
903        //return the data folder to root
904        SetDataFolder root:
905       
906        Return(0)
907End
908
909// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
910// pay attention to what is/not to be trusted due to "fake" information.
911// uses what it can from the header lines from the ASC file (hdrLines wave)
912//
913// destFolder is of the form "myGlobals:WorkMath:AAA"
914//
915//
916// called by WorkFileUtils.ipf
917//
918Function FillFakeHeader_ASC(destFolder)
919        String destFolder
920        Make/O/N=23 $("root:Packages:NIST:"+destFolder+":IntegersRead")
921        Make/O/N=52 $("root:Packages:NIST:"+destFolder+":RealsRead")
922        Make/O/T/N=11 $("root:Packages:NIST:"+destFolder+":TextRead")
923       
924        Wave intw=$("root:Packages:NIST:"+destFolder+":IntegersRead")
925        Wave realw=$("root:Packages:NIST:"+destFolder+":RealsRead")
926        Wave/T textw=$("root:Packages:NIST:"+destFolder+":TextRead")
927       
928        //Put in appropriate "fake" values
929        //parse values as needed from headerLines
930        Wave/T hdr=$("root:Packages:NIST:"+destFolder+":hdrLines")
931        Variable monCt,lam,offset,sdd,trans,thick
932        Variable xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam
933        String detTyp=""
934        String tempStr="",formatStr="",junkStr=""
935        formatStr = "%g %g %g %g %g %g"
936        tempStr=hdr[3]
937        sscanf tempStr, formatStr, monCt,lam,offset,sdd,trans,thick
938//      Print monCt,lam,offset,sdd,trans,thick,avStr,step
939        formatStr = "%g %g %g %g %g %g %g %s"
940        tempStr=hdr[5]
941        sscanf tempStr,formatStr,xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
942//      Print xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
943       
944        realw[16]=xCtr          //xCtr(pixels)
945        realw[17]=yCtr  //yCtr (pixels)
946        realw[18]=sdd           //SDD (m)
947        realw[26]=lam           //wavelength (A)
948        //
949        // necessary values
950        realw[10]=5                     //detector calibration constants, needed for averaging
951        realw[11]=10000
952        realw[12]=0
953        realw[13]=5
954        realw[14]=10000
955        realw[15]=0
956        //
957        // used in the resolution calculation, ONLY here to keep the routine from crashing
958        realw[20]=65            //det size
959        realw[27]=dlam  //delta lambda
960        realw[21]=bsDiam        //BS size
961        realw[23]=a1            //A1
962        realw[24]=a2    //A2
963        realw[25]=a1a2Dist      //A1A2 distance
964        realw[4]=trans          //trans
965        realw[3]=0              //atten
966        realw[5]=thick          //thick
967        //
968        //
969        realw[0]=monCt          //def mon cts
970
971        // fake values to get valid deadtime and detector constants
972        //
973        textw[9]=detTyp+"  "            //6 characters 4+2 spaces
974        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
975       
976        //set the string values
977        formatStr="FILE: %s CREATED: %s"
978        sscanf hdr[0],formatStr,tempStr,junkStr
979//      Print tempStr
980//      Print junkStr
981        String/G $("root:Packages:NIST:"+destFolder+":fileList") = tempStr
982        textw[0] = tempStr              //filename
983        textw[1] = junkStr              //run date-time
984       
985        //file label = hdr[1]
986        tempStr = hdr[1]
987        tempStr = tempStr[0,strlen(tempStr)-2]          //clean off the last LF
988//      Print tempStr
989        textW[6] = tempStr      //sample label
990       
991        return(0)
992End
993
994
995/////*****************
996////unused testing procedure for writing a 4 byte floating point value in VAX format
997//Proc TestReWriteReal()
998//      String Path
999//      Variable value,start
1000//     
1001//      GetFileAndPath()
1002//      Path = S_Path + S_filename
1003//     
1004//      value = 0.2222
1005//      start = 158             //trans starts at byte 159
1006//      ReWriteReal(path,value,start)
1007//     
1008//      SetDataFolder root:
1009//End
1010
1011//function will re-write a real value (4bytes) to the header of a RAW data file
1012//to ensure re-readability, the real value must be written mimicking VAX binary format
1013//which is done in this function
1014//path is the full path:file;vers to the file
1015//value is the real value to write
1016//start is the position to move the file marker to, to begin writing
1017//--so start is actually the "end byte" of the previous value
1018//
1019// Igor cannot write VAX FP values - so to "fake it"
1020// (1) write IEEE FP, 4*desired value, little endian
1021// (2) read back as two 16-bit integers, big endian
1022// (3) write the two 16-bit integers, reversed, writing each as big endian
1023//
1024//this procedure takes care of all file open/close pairs needed
1025//
1026Function WriteVAXReal(path,value,start)
1027        String path
1028        Variable value,start
1029       
1030        //Print " in F(), path = " + path
1031        Variable refnum,int1,int2, value4
1032
1033//////
1034        value4 = 4*value
1035       
1036        Open/A/T="????TEXT" refnum as path
1037        //write IEEE FP, 4*desired value
1038        FSetPos refnum,start
1039        FBinWrite/B=3/F=4 refnum,value4         //write out as little endian
1040        //move to the end of the file
1041        FStatus refnum
1042        FSetPos refnum,V_logEOF
1043        Close refnum
1044       
1045///////
1046        Open/R refnum as path
1047        //read back as two 16-bit integers
1048        FSetPos refnum,start
1049        FBinRead/B=2/F=2 refnum,int1    //read as big-endian
1050        FBinRead/B=2/F=2 refnum,int2   
1051        //file was opened read-only, no need to move to the end of the file, just close it     
1052        Close refnum
1053       
1054///////
1055        Open/A/T="????TEXT" refnum as path
1056        //write the two 16-bit integers, reversed
1057        FSetPos refnum,start
1058        FBinWrite/B=2/F=2 refnum,int2   //re-write as big endian
1059        FBinWrite/B=2/F=2 refnum,int1
1060        //move to the end of the file
1061        FStatus refnum
1062        FSetPos refnum,V_logEOF
1063        Close refnum            //at this point, it is as the VAX would have written it.
1064       
1065        Return(0)
1066End
1067
1068//sample transmission is a real value at byte 158
1069Function WriteTransmissionToHeader(fname,trans)
1070        String fname
1071        Variable trans
1072       
1073        WriteVAXReal(fname,trans,158)           //transmission start byte is 158
1074        return(0)
1075End
1076
1077//whole transmission is a real value at byte 392
1078Function WriteWholeTransToHeader(fname,trans)
1079        String fname
1080        Variable trans
1081       
1082        WriteVAXReal(fname,trans,392)           //transmission start byte is 392
1083        return(0)
1084End
1085
1086//box sum counts is a real value at byte 494
1087Function WriteBoxCountsToHeader(fname,counts)
1088        String fname
1089        Variable counts
1090       
1091        WriteVAXReal(fname,counts,494)          // start byte is 494
1092        return(0)
1093End
1094
1095//beam stop X-pos is at byte 368
1096Function WriteBSXPosToHeader(fname,xpos)
1097        String fname
1098        Variable xpos
1099       
1100        WriteVAXReal(fname,xpos,368)
1101        return(0)
1102End
1103
1104//sample thickness is at byte 162
1105Function WriteThicknessToHeader(fname,num)
1106        String fname
1107        Variable num
1108       
1109        WriteVAXReal(fname,num,162)
1110        return(0)
1111End
1112
1113//beam center X pixel location is at byte 252
1114Function WriteBeamCenterXToHeader(fname,num)
1115        String fname
1116        Variable num
1117       
1118        WriteVAXReal(fname,num,252)
1119        return(0)
1120End
1121
1122//beam center Y pixel location is at byte 256
1123Function WriteBeamCenterYToHeader(fname,num)
1124        String fname
1125        Variable num
1126       
1127        WriteVAXReal(fname,num,256)
1128        return(0)
1129End
1130
1131//attenuator number (not its transmission) is at byte 51
1132Function WriteAttenNumberToHeader(fname,num)
1133        String fname
1134        Variable num
1135       
1136        WriteVAXReal(fname,num,51)
1137        return(0)
1138End
1139
1140//monitor count is at byte 39
1141Function WriteMonitorCountToHeader(fname,num)
1142        String fname
1143        Variable num
1144       
1145        WriteVAXReal(fname,num,39)
1146        return(0)
1147End
1148
1149//total detector count is at byte 47
1150Function WriteDetectorCountToHeader(fname,num)
1151        String fname
1152        Variable num
1153       
1154        WriteVAXReal(fname,num,47)
1155        return(0)
1156End
1157
1158//transmission detector count is at byte 388
1159Function WriteTransDetCountToHeader(fname,num)
1160        String fname
1161        Variable num
1162       
1163        WriteVAXReal(fname,num,388)
1164        return(0)
1165End
1166
1167//wavelength is at byte 292
1168Function WriteWavelengthToHeader(fname,num)
1169        String fname
1170        Variable num
1171       
1172        WriteVAXReal(fname,num,292)
1173        return(0)
1174End
1175
1176//wavelength spread is at byte 296
1177Function WriteWavelengthDistrToHeader(fname,num)
1178        String fname
1179        Variable num
1180       
1181        WriteVAXReal(fname,num,296)
1182        return(0)
1183End
1184
1185//temperature is at byte 186
1186Function WriteTemperatureToHeader(fname,num)
1187        String fname
1188        Variable num
1189       
1190        WriteVAXReal(fname,num,186)
1191        return(0)
1192End
1193
1194//magnetic field is at byte 190
1195Function WriteMagnFieldToHeader(fname,num)
1196        String fname
1197        Variable num
1198       
1199        WriteVAXReal(fname,num,190)
1200        return(0)
1201End
1202
1203//Source Aperture diameter is at byte 280
1204Function WriteSourceApDiamToHeader(fname,num)
1205        String fname
1206        Variable num
1207       
1208        WriteVAXReal(fname,num,280)
1209        return(0)
1210End
1211
1212//Sample Aperture diameter is at byte 284
1213Function WriteSampleApDiamToHeader(fname,num)
1214        String fname
1215        Variable num
1216       
1217        WriteVAXReal(fname,num,284)
1218        return(0)
1219End
1220
1221//Source to sample distance is at byte 288
1222Function WriteSrcToSamDistToHeader(fname,num)
1223        String fname
1224        Variable num
1225       
1226        WriteVAXReal(fname,num,288)
1227        return(0)
1228End
1229
1230//detector offset is at byte 264
1231Function WriteDetectorOffsetToHeader(fname,num)
1232        String fname
1233        Variable num
1234       
1235        WriteVAXReal(fname,num,264)
1236        return(0)
1237End
1238
1239//beam stop diameter is at byte 272
1240Function WriteBeamStopDiamToHeader(fname,num)
1241        String fname
1242        Variable num
1243       
1244        WriteVAXReal(fname,num,272)
1245        return(0)
1246End
1247
1248//sample to detector distance is at byte 260
1249Function WriteSDDToHeader(fname,num)
1250        String fname
1251        Variable num
1252       
1253        WriteVAXReal(fname,num,260)
1254        return(0)
1255End
1256
1257//detector pixel X size (mm) is at byte 220
1258Function WriteDetPixelXToHeader(fname,num)
1259        String fname
1260        Variable num
1261       
1262        WriteVAXReal(fname,num,220)
1263        return(0)
1264End
1265
1266//detector pixel Y size (mm) is at byte 232
1267Function WriteDetPixelYToHeader(fname,num)
1268        String fname
1269        Variable num
1270       
1271        WriteVAXReal(fname,num,232)
1272        return(0)
1273End
1274
1275//rewrite a text field back to the header
1276// fname is the full path:name
1277// str is the CORRECT length - it will all be written - pad or trim before passing
1278// start is the start byte
1279Function WriteTextToHeader(fname,str,start)
1280        String fname,str
1281        Variable start
1282       
1283        Variable refnum
1284        Open/A/T="????TEXT" refnum as fname      //Open for writing! Move to EOF before closing!
1285        FSetPos refnum,start
1286        FBinWrite/F=0 refnum, str      //native object format (character)
1287        //move to the end of the file before closing
1288        FStatus refnum
1289        FSetPos refnum,V_logEOF
1290        Close refnum
1291               
1292        return(0)
1293end
1294
1295// sample label, starts at byte 98
1296// limit to 60 characters
1297Function WriteSamLabelToHeader(fname,str)
1298        String fname,str
1299       
1300        if(strlen(str) > 60)
1301                str = str[0,59]
1302        endif
1303        WriteTextToHeader(fname,str,98)
1304        return(0)
1305End
1306
1307//user account name, starts at byte 78
1308// limit to 11 characters
1309Function WriteAcctNameToHeader(fname,str)
1310        String fname,str
1311       
1312        if(strlen(str) > 9)
1313                str = str[0,8]
1314        endif
1315        str = "["+str+"]"
1316        WriteTextToHeader(fname,str,78)
1317        return(0)
1318End
1319
1320// file name, starts at byte 2
1321// limit to 21 characters
1322//
1323// be sure that any white space to pad to 21 characters is at the front of the string
1324Function WriteFileNameToHeader(fname,str)
1325        String fname,str
1326       
1327        Variable i
1328        String newStr=""
1329//      printf "\"%s\"\t%d\r",str,strlen(str)
1330
1331        //strip any white spaces from the end (from TrimWSR(str) in cansasXML.ipf)
1332        for (i=strlen(str)-1; char2num(str[i])<=32 && i>=0; i-=1)    // find last non-white space
1333        endfor
1334        str = str[0,i]
1335//      printf "\"%s\"\t%d\r",str,strlen(str)
1336
1337        // if the string is less than 21 characters, fix it with white space at the beginning
1338        if(strlen(str) < 21)
1339                newStr = PadString(newStr,21,0x20)              //pad with fortran-style spaces
1340                newStr[21-strlen(str),20] = str
1341        else
1342                newStr = str
1343        endif
1344//      printf "\"%s\"\t%d\r",newstr,strlen(newstr)
1345
1346        WriteTextToHeader(fname,newstr,2)
1347        return(0)
1348End
1349
1350
1351//rewrite an integer field back to the header
1352// fname is the full path:name
1353// val is the integer value
1354// start is the start byte
1355Function RewriteIntegerToHeader(fname,val,start)
1356        String fname
1357        Variable val,start
1358       
1359        Variable refnum
1360        Open/A/T="????TEXT" refnum as fname      //Open for writing! Move to EOF before closing!
1361        FSetPos refnum,start
1362        FBinWrite/B=3/F=3 refnum, val      //write a 4-byte integer
1363        //move to the end of the file before closing
1364        FStatus refnum
1365        FSetPos refnum,V_logEOF
1366        Close refnum
1367               
1368        return(0)
1369end
1370
1371Function WriteCountTimeToHeader(fname,num)
1372        String fname
1373        Variable num
1374       
1375        RewriteIntegerToHeader(fname,num,31)
1376        return(0)
1377End
1378
1379// read specific bits of information from the header
1380// each of these operations MUST take care of open/close on their own
1381
1382Function/S getStringFromHeader(fname,start,num)
1383        String fname                            //full path:name
1384        Variable start,num              //starting byte and number of characters to read
1385       
1386        String str
1387        Variable refnum
1388        Open/R refNum as fname
1389        FSetPos refNum,start
1390        FReadLine/N=(num) refNum,str
1391        Close refnum
1392       
1393        return(str)
1394End
1395
1396// file suffix (4 characters @ byte 19)
1397Function/S getSuffix(fname)
1398        String fname
1399       
1400        return(getStringFromHeader(fname,19,4))
1401End
1402
1403// associated file suffix (for transmission) (4 characters @ byte 404)
1404Function/S getAssociatedFileSuffix(fname)
1405        String fname
1406       
1407        return(getStringFromHeader(fname,404,4))
1408End
1409
1410// sample label (60 characters @ byte 98)
1411Function/S getSampleLabel(fname)
1412        String fname
1413       
1414        return(getStringFromHeader(fname,98,60))
1415End
1416
1417// file creation date (20 characters @ byte 55)
1418Function/S getFileCreationDate(fname)
1419        String fname
1420       
1421        return(getStringFromHeader(fname,55,20))
1422End
1423
1424// user account (11 characters @ byte 78)
1425Function/S getAcctName(fname)
1426        String fname
1427       
1428        return(getStringFromHeader(fname,78,11))
1429End
1430
1431// file name (21 characters @ byte 2)
1432Function/S getFileName(fname)
1433        String fname
1434       
1435        return(getStringFromHeader(fname,2,21))
1436End
1437
1438
1439// read a single real value with GBLoadWave
1440Function getRealValueFromHeader(fname,start)
1441        String fname
1442        Variable start
1443
1444        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
1445       
1446        GBLoadStr += "/S="+num2str(start)+"/U=1" + "\"" + fname + "\""
1447        Execute GBLoadStr
1448        Wave w=$"tempGBWave0"
1449       
1450        return(w[0])
1451End
1452
1453//monitor count is at byte 39
1454Function getMonitorCount(fname)
1455        String fname
1456       
1457        return(getRealValueFromHeader(fname,39))
1458end
1459
1460//saved monitor count is at byte 43
1461Function getSavMon(fname)
1462        String fname
1463       
1464        return(getRealValueFromHeader(fname,43))
1465end
1466
1467//detector count is at byte 47
1468Function getDetCount(fname)
1469        String fname
1470       
1471        return(getRealValueFromHeader(fname,47))
1472end
1473
1474//Attenuator number is at byte 51
1475Function getAttenNumber(fname)
1476        String fname
1477       
1478        return(getRealValueFromHeader(fname,51))
1479end
1480
1481//transmission is at byte 158
1482Function getSampleTrans(fname)
1483        String fname
1484       
1485        return(getRealValueFromHeader(fname,158))
1486end
1487
1488//box counts are stored at byte 494
1489Function getBoxCounts(fname)
1490        String fname
1491       
1492        return(getRealValueFromHeader(fname,494))
1493end
1494
1495//whole detector trasmission is at byte 392
1496Function getSampleTransWholeDetector(fname)
1497        String fname
1498       
1499        return(getRealValueFromHeader(fname,392))
1500end
1501
1502//SampleThickness is at byte 162
1503Function getSampleThickness(fname)
1504        String fname
1505       
1506        return(getRealValueFromHeader(fname,162))
1507end
1508
1509//Sample Rotation Angle is at byte 170
1510Function getSampleRotationAngle(fname)
1511        String fname
1512       
1513        return(getRealValueFromHeader(fname,170))
1514end
1515
1516//temperature is at byte 186
1517Function getTemperature(fname)
1518        String fname
1519       
1520        return(getRealValueFromHeader(fname,186))
1521end
1522
1523//field strength is at byte 190
1524// 190 is not the right location, 348 looks to be correct for the electromagnets, 450 for the
1525// superconducting magnet. Although each place is only the voltage, it is correct
1526Function getFieldStrength(fname)
1527        String fname
1528       
1529//      return(getRealValueFromHeader(fname,190))
1530        return(getRealValueFromHeader(fname,348))
1531end
1532
1533//beam xPos is at byte 252
1534Function getBeamXPos(fname)
1535        String fname
1536       
1537        return(getRealValueFromHeader(fname,252))
1538end
1539
1540//beam Y pos is at byte 256
1541Function getBeamYPos(fname)
1542        String fname
1543       
1544        return(getRealValueFromHeader(fname,256))
1545end
1546
1547//sample to detector distance is at byte 260
1548Function getSDD(fname)
1549        String fname
1550       
1551        return(getRealValueFromHeader(fname,260))
1552end
1553
1554//detector offset is at byte 264
1555Function getDetectorOffset(fname)
1556        String fname
1557       
1558        return(getRealValueFromHeader(fname,264))
1559end
1560
1561//Beamstop diameter is at byte 272
1562Function getBSDiameter(fname)
1563        String fname
1564       
1565        return(getRealValueFromHeader(fname,272))
1566end
1567
1568//source aperture diameter is at byte 280
1569Function getSourceApertureDiam(fname)
1570        String fname
1571       
1572        return(getRealValueFromHeader(fname,280))
1573end
1574
1575//sample aperture diameter is at byte 284
1576Function getSampleApertureDiam(fname)
1577        String fname
1578       
1579        return(getRealValueFromHeader(fname,284))
1580end
1581
1582//source AP to Sample AP distance is at byte 288
1583Function getSourceToSampleDist(fname)
1584        String fname
1585       
1586        return(getRealValueFromHeader(fname,288))
1587end
1588
1589//wavelength is at byte 292
1590Function getWavelength(fname)
1591        String fname
1592       
1593        return(getRealValueFromHeader(fname,292))
1594end
1595
1596//wavelength spread is at byte 296
1597Function getWavelengthSpread(fname)
1598        String fname
1599       
1600        return(getRealValueFromHeader(fname,296))
1601end
1602
1603//transmission detector count is at byte 388
1604Function getTransDetectorCounts(fname)
1605        String fname
1606       
1607        return(getRealValueFromHeader(fname,388))
1608end
1609
1610//detector pixel X size is at byte 220
1611Function getDetectorPixelXSize(fname)
1612        String fname
1613       
1614        return(getRealValueFromHeader(fname,220))
1615end
1616
1617//detector pixel Y size is at byte 232
1618Function getDetectorPixelYSize(fname)
1619        String fname
1620       
1621        return(getRealValueFromHeader(fname,232))
1622end
1623
1624// stub for ILL - power is written to their header, not ours
1625Function getReactorPower(fname)
1626        String fname
1627
1628        return 0
1629
1630end
1631
1632//////  integer values
1633
1634Function getIntegerFromHeader(fname,start)
1635        String fname                            //full path:name
1636        Variable start          //starting byte
1637       
1638        Variable refnum,val
1639        Open/R refNum as fname
1640        FSetPos refNum,start
1641        FBinRead/B=3/F=3 refnum,val
1642        Close refnum
1643       
1644        return(val)
1645End
1646
1647//total count time is at byte 31       
1648Function getCountTime(fname)
1649        String fname
1650        return(getIntegerFromHeader(fname,31))
1651end
1652
1653
1654//reads the wavelength from a reduced data file (not very reliable)
1655// - does not work with NSORTed files
1656// - only used in FIT/RPA (which itself is almost NEVER used...)
1657//
1658Function GetLambdaFromReducedData(tempName)
1659        String tempName
1660       
1661        String junkString
1662        Variable lambdaFromFile, fileVar
1663        lambdaFromFile = 6.0
1664        Open/R/P=catPathName fileVar as tempName
1665        FReadLine fileVar, junkString
1666        FReadLine fileVar, junkString
1667        FReadLine fileVar, junkString
1668        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
1669                FReadLine/N=11 fileVar, junkString
1670                FReadLine/N=10 fileVar, junkString
1671                lambdaFromFile = str2num(junkString)
1672        endif
1673        Close fileVar
1674       
1675        return(lambdaFromFile)
1676End
1677
1678/////   TRANSMISSION RELATED FUNCTIONS    ////////
1679//box coordinate are returned by reference
1680// filename is the full path:name
1681Function getXYBoxFromFile(filename,x1,x2,y1,y2)
1682        String filename
1683        Variable &x1,&x2,&y1,&y2
1684       
1685        Variable refnum
1686//      String tmpFile = FindValidFilename(filename)
1687               
1688//      Open/R/P=catPathName refnum as tmpFile
1689        Open/R refnum as filename
1690        FSetPos refnum,478
1691        FBinRead/F=3/B=3 refnum, x1
1692        FBinRead/F=3/B=3 refnum, x2
1693        FBinRead/F=3/B=3 refnum, y1
1694        FBinRead/F=3/B=3 refnum, y2
1695        Close refnum
1696       
1697        return(0)
1698End
1699
1700//go find the file, open it and write 4 integers to the file
1701//in the positions for analysis.rows(2), .cols(2) = 4 unused 4byte integers
1702Function WriteXYBoxToHeader(filename,x1,x2,y1,y2)
1703        String filename
1704        Variable x1,x2,y1,y2
1705       
1706        Variable refnum
1707        Open/A/T="????TEXT" refnum as filename
1708        FSetPos refnum,478
1709        FBinWrite/F=3/B=3 refNum, x1
1710        FBinWrite/F=3/B=3 refNum, x2
1711        FBinWrite/F=3/B=3 refNum, y1
1712        FBinWrite/F=3/B=3 refNum, y2
1713        //move to the end of the file before closing
1714        FStatus refnum
1715        FSetPos refnum,V_logEOF
1716        Close refnum
1717       
1718        return(0)
1719End
1720
1721//associated file suffix is the first 4 characters of a text field starting
1722// at byte 404
1723// suffix must be four characters long, if not, it's truncated
1724//
1725Function WriteAssocFileSuffixToHeader(fname,suffix)
1726        String fname,suffix
1727               
1728        suffix = suffix[0,3]            //limit to 4 characters
1729        WriteTextToHeader(fname,suffix,404)
1730       
1731        return(0)
1732end
1733
1734
1735// Jan 2008
1736// it has been determined that the true pixel dimension of the ordela detectors is not 5.0 mm
1737// but somewhat larger (5.08? mm). "new" data files will be written out with the proper size
1738// and old files will be patched batchwise to put the prpoer value in the header
1739
1740Proc PatchDetectorPixelSize(firstFile,lastFile,XSize,YSize)
1741        Variable firstFile=1,lastFile=100,XSize=5.08,YSize=5.08
1742
1743        fPatchDetectorPixelSize(firstFile,lastFile,XSize,YSize)
1744
1745End
1746
1747Proc ReadDetectorPixelSize(firstFile,lastFile)
1748        Variable firstFile=1,lastFile=100
1749       
1750        fReadDetectorPixelSize(firstFile,lastFile)
1751End
1752
1753// simple utility to patch the detector pixel size in the file headers
1754// pass in the dimensions in mm
1755// lo is the first file number
1756// hi is the last file number (inclusive)
1757//
1758Function fPatchDetectorPixelSize(lo,hi,xdim,ydim)
1759        Variable lo,hi,xdim,ydim
1760       
1761        Variable ii
1762        String file
1763       
1764        //loop over all files
1765        for(ii=lo;ii<=hi;ii+=1)
1766                file = FindFileFromRunNumber(ii)
1767                if(strlen(file) != 0)
1768                        WriteDetPixelXToHeader(file,xdim)
1769                        WriteDetPixelyToHeader(file,ydim)
1770                else
1771                        printf "run number %d not found\r",ii
1772                endif
1773        endfor
1774       
1775        return(0)
1776End
1777
1778// simple utility to read the pixel size stored in the file header
1779Function fReadDetectorPixelSize(lo,hi)
1780        Variable lo,hi
1781       
1782        String file
1783        Variable xdim,ydim,ii
1784       
1785        for(ii=lo;ii<=hi;ii+=1)
1786                file = FindFileFromRunNumber(ii)
1787                if(strlen(file) != 0)
1788                        xdim = getDetectorPixelXSize(file)
1789                        ydim = getDetectorPixelYSize(file)
1790                        printf "File %d:  Pixel dimensions (mm): X = %g\t Y = %g\r",ii,xdim,ydim
1791                else
1792                        printf "run number %d not found\r",ii
1793                endif
1794        endfor
1795       
1796        return(0)
1797End
1798
1799
1800
1801//*******************
1802//************
1803// simple command - line utilities to convert/unconvert the header value
1804// that flags files as using lenses
1805//
1806// stored in reals[28], header byte start @ 300
1807//
1808// currently, two values (0 | 1) = (no lens | yes lens)
1809// ideally, this field will have the actual number of lenses inserted.
1810//
1811// this is used in getResolution (reads the reals[]) and switches the calculation
1812//************
1813
1814Proc ConvertToLens(RunNumber)
1815        Variable RunNumber
1816        HeaderToLensResolution(RunNumber)
1817End
1818
1819Proc ConvertToPinhole(RunNumber)
1820        Variable RunNumber
1821        HeaderToPinholeResolution(RunNumber)
1822End
1823
1824// sets the flag to zero in the file (= 0)
1825Function HeaderToPinholeResolution(num)
1826        Variable num   
1827       
1828        //Print "UnConvert"
1829        String fullname=""
1830       
1831        fullname = FindFileFromRunNumber(num)
1832        Print fullname
1833        //report error or change the file
1834        if(cmpstr(fullname,"")==0)
1835                Print "HeaderToPinhole - file not found"
1836        else
1837                //Print "Unconvert",fullname
1838                WriteVAXReal(fullname,0,300)
1839        Endif
1840        return(0)
1841End
1842
1843// sets the flag to one in the file (= 1)
1844Function HeaderToLensResolution(num)
1845        Variable num   
1846       
1847        //Print "UnConvert"
1848        String fullname=""
1849       
1850        fullname = FindFileFromRunNumber(num)
1851        Print fullname
1852        //report error or change the file
1853        if(cmpstr(fullname,"")==0)
1854                Print "HeaderToPinhole - file not found"
1855        else
1856                //Print "Unconvert",fullname
1857                WriteVAXReal(fullname,1,300)
1858        Endif
1859        return(0)
1860End
1861
1862
1863// given a data folder, write out the corresponding VAX binary data file.
1864//
1865// I don't think that I can generate a STRUCT and then lay that down - since the
1866// VAX FP format has to be duplicated with a write/read/flip/re-write dance...
1867//
1868// seems to work correctly byte for byte
1869// compression has bee implmented also, for complete replication of the format (n>32767 in a cell)
1870//
1871// SRK 29JAN09
1872//
1873// other functions needed:
1874//
1875//
1876// one to generate a fake data file name, and put the matching name in the data header
1877// !! must fake the Annn suffix too! this is used...
1878// use a prefix, keep a run number, initials SIM, and alpha as before (start randomly, don't bother changing?)
1879//
1880// for right now, keep a run number, and generate
1881// PREFIXnnn.SA2_SIM_Annn
1882// also, start the index @ 100 to avoid leading zeros (although I have the functions available)
1883
1884// one to generate the date/time string in VAX format, right # characters// Print Secs2Time(DateTime,3)                         // Prints 13:07:29
1885// Print Secs2Time(DateTime,3)                          // Prints 13:07:29
1886//      Print Secs2Date(DateTime,-2)            // 1993-03-14                   //this call is independent of System date/time!//
1887//
1888// for now, 20 characters 01-JAN-2009 12:12:12
1889//
1890
1891// simulation should call as ("SAS","",0) to bypass the dialog, and to fill the header
1892// this could be modified in the future to be more generic
1893//
1894///
1895Function WriteVAXData(type,fullpath,dialog)
1896        String type,fullpath
1897        Variable dialog         //=1 will present dialog for name
1898       
1899        String destStr=""
1900        Variable refNum,ii,val,err
1901       
1902       
1903        destStr = "root:Packages:NIST:"+type
1904       
1905        SetDataFolder $destStr
1906        WAVE intw=integersRead
1907        WAVE rw=realsRead
1908        WAVE/T textw=textRead
1909        WAVE data=linear_data
1910       
1911        //check each wave
1912        If(!(WaveExists(intw)))
1913                Abort "intw DNExist WriteVAXData()"
1914        Endif
1915        If(!(WaveExists(rw)))
1916                Abort "rw DNExist WriteVAXData()"
1917        Endif
1918        If(!(WaveExists(textw)))
1919                Abort "textw DNExist WriteVAXData()"
1920        Endif
1921        If(!(WaveExists(data)))
1922                Abort "linear_data DNExist WriteVAXData()"
1923        Endif
1924       
1925       
1926//      if(dialog)
1927//              PathInfo/S catPathName
1928//              fullPath = DoSaveFileDialog("Save data as")
1929//              If(cmpstr(fullPath,"")==0)
1930//                      //user cancel, don't write out a file
1931//                      Close/A
1932//                      Abort "no data file was written"
1933//              Endif
1934//              //Print "dialog fullpath = ",fullpath
1935//      Endif
1936       
1937        // save to home, or get out
1938        //
1939        PathInfo home
1940        if(V_flag       == 0)
1941                Abort "no save path defined. Save the experiment to generate a home path"
1942        endif
1943       
1944        fullPath = S_path               //not the full path yet, still need the name, after the header is filled
1945       
1946       
1947        Make/O/B/U/N=33316 tmpFile              //unsigned integers for a blank data file
1948        tmpFile=0
1949       
1950        Make/O/W/N=16401 dataWRecMarkers
1951        AddRecordMarkers(data,dataWRecMarkers)
1952       
1953        // need to re-compress?? maybe never a problem, but should be done for the odd case
1954        dataWRecMarkers = CompressI4toI2(dataWRecMarkers)               //unless a pixel value is > 32767, the same values are returned
1955       
1956        // fill the last bits of the header information
1957        err = SimulationVAXHeader(type)
1958        if (err == -1)
1959                Abort "no sample label entered - no file written"                       // User did not fill in header correctly/completely
1960        endif
1961        fullPath = fullPath + textW[0]
1962       
1963        // lay down a blank file
1964        Open refNum as fullpath
1965                FBinWrite refNum,tmpFile                        //file is the right size, but all zeroes
1966        Close refNum
1967       
1968        // fill up the header
1969        // text values
1970        // elements of textW are already the correct length set by the read, but just make sure
1971        String str
1972       
1973        if(strlen(textw[0])>21)
1974                textw[0] = (textw[0])[0,20]
1975        endif
1976        if(strlen(textw[1])>20)
1977                textw[1] = (textw[1])[0,19]
1978        endif
1979        if(strlen(textw[2])>3)
1980                textw[2] = (textw[2])[0,2]
1981        endif
1982        if(strlen(textw[3])>11)
1983                textw[3] = (textw[3])[0,10]
1984        endif
1985        if(strlen(textw[4])>1)
1986                textw[4] = (textw[4])[0]
1987        endif
1988        if(strlen(textw[5])>8)
1989                textw[5] = (textw[5])[0,7]
1990        endif
1991        if(strlen(textw[6])>60)
1992                textw[6] = (textw[6])[0,59]
1993        endif
1994        if(strlen(textw[7])>6)
1995                textw[7] = (textw[7])[0,5]
1996        endif
1997        if(strlen(textw[8])>6)
1998                textw[8] = (textw[8])[0,5]
1999        endif
2000        if(strlen(textw[9])>6)
2001                textw[9] = (textw[9])[0,5]
2002        endif
2003        if(strlen(textw[10])>42)
2004                textw[10] = (textw[10])[0,41]
2005        endif   
2006       
2007        ii=0
2008        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
2009                str = textW[ii]
2010                FSetPos refnum,2                                                        ////file name
2011                FBinWrite/F=0 refnum, str      //native object format (character)
2012                ii+=1
2013                str = textW[ii]
2014                FSetPos refnum,55                                                       ////date/time
2015                FBinWrite/F=0 refnum, str
2016                ii+=1
2017                str = textW[ii]
2018                FSetPos refnum,75                                                       ////type
2019                FBinWrite/F=0 refnum, str
2020                ii+=1
2021                str = textW[ii]
2022                FSetPos refnum,78                                               ////def dir
2023                FBinWrite/F=0 refnum, str
2024                ii+=1
2025                str = textW[ii]
2026                FSetPos refnum,89                                               ////mode
2027                FBinWrite/F=0 refnum, str
2028                ii+=1
2029                str = textW[ii]
2030                FSetPos refnum,90                                               ////reserve
2031                FBinWrite/F=0 refnum, str
2032                ii+=1
2033                str = textW[ii]
2034                FSetPos refnum,98                                               ////@98, sample label
2035                FBinWrite/F=0 refnum, str
2036                ii+=1
2037                str = textW[ii]
2038                FSetPos refnum,202                                              //// T units
2039                FBinWrite/F=0 refnum, str
2040                ii+=1
2041                str = textW[ii]
2042                FSetPos refnum,208                                              //// F units
2043                FBinWrite/F=0 refnum, str
2044                ii+=1
2045                str = textW[ii]
2046                FSetPos refnum,214                                              ////det type
2047                FBinWrite/F=0 refnum, str
2048                ii+=1
2049                str = textW[ii]
2050                FSetPos refnum,404                                              ////reserve
2051                FBinWrite/F=0 refnum, str
2052       
2053                //move to the end of the file before closing
2054                FStatus refnum
2055                FSetPos refnum,V_logEOF
2056        Close refnum
2057       
2058       
2059        // integer values (4 bytes)
2060        ii=0
2061        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
2062                val = intw[ii]
2063                FSetPos refnum,23                                                       //nprefactors
2064                FBinWrite/B=3/F=3 refnum, val      //write a 4-byte integer
2065                ii+=1
2066                val=intw[ii]
2067                FSetPos refnum,27                                                       //ctime
2068                FBinWrite/B=3/F=3 refnum, val
2069                ii+=1
2070                val=intw[ii]
2071                FSetPos refnum,31                                                       //rtime
2072                FBinWrite/B=3/F=3 refnum, val
2073                ii+=1
2074                val=intw[ii]
2075                FSetPos refnum,35                                                       //numruns
2076                FBinWrite/B=3/F=3 refnum, val
2077                ii+=1
2078                val=intw[ii]
2079                FSetPos refnum,174                                                      //table
2080                FBinWrite/B=3/F=3 refnum, val
2081                ii+=1
2082                val=intw[ii]
2083                FSetPos refnum,178                                                      //holder
2084                FBinWrite/B=3/F=3 refnum, val
2085                ii+=1
2086                val=intw[ii]
2087                FSetPos refnum,182                                                      //blank
2088                FBinWrite/B=3/F=3 refnum, val
2089                ii+=1
2090                val=intw[ii]
2091                FSetPos refnum,194                                                      //tctrlr
2092                FBinWrite/B=3/F=3 refnum, val
2093                ii+=1
2094                val=intw[ii]
2095                FSetPos refnum,198                                                      //magnet
2096                FBinWrite/B=3/F=3 refnum, val
2097                ii+=1
2098                val=intw[ii]
2099                FSetPos refnum,244                                                      //det num
2100                FBinWrite/B=3/F=3 refnum, val
2101                ii+=1
2102                val=intw[ii]
2103                FSetPos refnum,248                                                      //det spacer
2104                FBinWrite/B=3/F=3 refnum, val
2105                ii+=1
2106                val=intw[ii]
2107                FSetPos refnum,308                                                      //tslice mult
2108                FBinWrite/B=3/F=3 refnum, val
2109                ii+=1
2110                val=intw[ii]
2111                FSetPos refnum,312                                                      //tsclice ltslice
2112                FBinWrite/B=3/F=3 refnum, val
2113                ii+=1
2114                val=intw[ii]
2115                FSetPos refnum,332                                                      //extra
2116                FBinWrite/B=3/F=3 refnum, val
2117                ii+=1
2118                val=intw[ii]
2119                FSetPos refnum,336                                                      //reserve
2120                FBinWrite/B=3/F=3 refnum, val
2121                ii+=1
2122                val=intw[ii]
2123                FSetPos refnum,376                                                      //blank1
2124                FBinWrite/B=3/F=3 refnum, val
2125                ii+=1
2126                val=intw[ii]
2127                FSetPos refnum,380                                                      //blank2
2128                FBinWrite/B=3/F=3 refnum, val
2129                ii+=1
2130                val=intw[ii]
2131                FSetPos refnum,384                                                      //blank3
2132                FBinWrite/B=3/F=3 refnum, val
2133                ii+=1
2134                val=intw[ii]
2135                FSetPos refnum,458                                                      //spacer
2136                FBinWrite/B=3/F=3 refnum, val
2137                ii+=1
2138                val=intw[ii]
2139                FSetPos refnum,478                                                      //box x1
2140                FBinWrite/B=3/F=3 refnum, val
2141                ii+=1
2142                val=intw[ii]
2143                FSetPos refnum,482                                                      //box x2
2144                FBinWrite/B=3/F=3 refnum, val
2145                ii+=1
2146                val=intw[ii]
2147                FSetPos refnum,486                                                      //box y1
2148                FBinWrite/B=3/F=3 refnum, val
2149                ii+=1
2150                val=intw[ii]
2151                FSetPos refnum,490                                                      //box y2
2152                FBinWrite/B=3/F=3 refnum, val
2153               
2154                //move to the end of the file before closing
2155                FStatus refnum
2156                FSetPos refnum,V_logEOF
2157        Close refnum
2158       
2159               
2160        //VAX 4-byte FP values. No choice here but to write/read/re-write to get
2161        // the proper format. there are 52! values to write
2162        //WriteVAXReal(fullpath,rw[n],start)
2163        // [0]
2164        WriteVAXReal(fullpath,rw[0],39)
2165        WriteVAXReal(fullpath,rw[1],43)
2166        WriteVAXReal(fullpath,rw[2],47)
2167        WriteVAXReal(fullpath,rw[3],51)
2168        WriteVAXReal(fullpath,rw[4],158)
2169        WriteVAXReal(fullpath,rw[5],162)
2170        WriteVAXReal(fullpath,rw[6],166)
2171        WriteVAXReal(fullpath,rw[7],170)
2172        WriteVAXReal(fullpath,rw[8],186)
2173        WriteVAXReal(fullpath,rw[9],190)
2174        // [10]
2175        WriteVAXReal(fullpath,rw[10],220)
2176        WriteVAXReal(fullpath,rw[11],224)
2177        WriteVAXReal(fullpath,rw[12],228)
2178        WriteVAXReal(fullpath,rw[13],232)
2179        WriteVAXReal(fullpath,rw[14],236)
2180        WriteVAXReal(fullpath,rw[15],240)
2181        WriteVAXReal(fullpath,rw[16],252)
2182        WriteVAXReal(fullpath,rw[17],256)
2183        WriteVAXReal(fullpath,rw[18],260)
2184        WriteVAXReal(fullpath,rw[19],264)
2185        // [20]
2186        WriteVAXReal(fullpath,rw[20],268)
2187        WriteVAXReal(fullpath,rw[21],272)
2188        WriteVAXReal(fullpath,rw[22],276)
2189        WriteVAXReal(fullpath,rw[23],280)
2190        WriteVAXReal(fullpath,rw[24],284)
2191        WriteVAXReal(fullpath,rw[25],288)
2192        WriteVAXReal(fullpath,rw[26],292)
2193        WriteVAXReal(fullpath,rw[27],296)
2194        WriteVAXReal(fullpath,rw[28],300)
2195        WriteVAXReal(fullpath,rw[29],320)
2196        // [30]
2197        WriteVAXReal(fullpath,rw[30],324)
2198        WriteVAXReal(fullpath,rw[31],328)
2199        WriteVAXReal(fullpath,rw[32],348)
2200        WriteVAXReal(fullpath,rw[33],352)
2201        WriteVAXReal(fullpath,rw[34],356)
2202        WriteVAXReal(fullpath,rw[35],360)
2203        WriteVAXReal(fullpath,rw[36],364)
2204        WriteVAXReal(fullpath,rw[37],368)
2205        WriteVAXReal(fullpath,rw[38],372)
2206        WriteVAXReal(fullpath,rw[39],388)
2207        // [40]
2208        WriteVAXReal(fullpath,rw[40],392)
2209        WriteVAXReal(fullpath,rw[41],396)
2210        WriteVAXReal(fullpath,rw[42],400)
2211        WriteVAXReal(fullpath,rw[43],450)
2212        WriteVAXReal(fullpath,rw[44],454)
2213        WriteVAXReal(fullpath,rw[45],470)
2214        WriteVAXReal(fullpath,rw[46],474)
2215        WriteVAXReal(fullpath,rw[47],494)
2216        WriteVAXReal(fullpath,rw[48],498)
2217        WriteVAXReal(fullpath,rw[49],502)
2218        // [50]
2219        WriteVAXReal(fullpath,rw[50],506)
2220        WriteVAXReal(fullpath,rw[51],510)
2221       
2222       
2223        // write out the data
2224        Open refNum as fullpath
2225                FSetPos refnum,514                                      //  OK
2226                FBinWrite/F=2/B=3 refNum,dataWRecMarkers                //don't trust the native format
2227                FStatus refNum
2228                FSetPos refNum,V_logEOF
2229        Close refNum
2230       
2231        // all done
2232        Killwaves/Z tmpFile,dataWRecMarkers
2233       
2234        Print "Saved VAX binary data as:  ",textW[0]
2235        SetDatafolder root:
2236        return(0)
2237End
2238
2239
2240Function AddRecordMarkers(in,out)
2241        Wave in,out
2242       
2243        Variable skip,ii
2244
2245//      Duplicate/O in,out
2246//      Redimension/N=16401 out
2247
2248        out=0
2249       
2250        ii=0
2251        skip=0
2252        out[ii] = 1
2253        ii+=1
2254        do
2255                if(mod(ii+skip,1022)==0)
2256                        out[ii+skip] = 0                //999999
2257                        skip+=1                 //increment AFTER filling the current marker
2258                endif
2259                out[ii+skip] = in[ii-1]
2260                ii+=1
2261        while(ii<=16384)
2262       
2263       
2264        return(0)
2265End
2266
2267
2268
2269
2270//        INTEGER*2 FUNCTION I4ToI2(I4)
2271//C
2272//C       Original author : Jim Rhyne
2273//C       Modified by     : Frank Chen 09/26/90
2274//C
2275//C       I4ToI2 = I4,                            I4 in [0,32767]
2276//C       I4ToI2 = -777,                          I4 in (2767000,...)
2277//C       I4ToI2 mapped to -13277 to -32768,      otherwise
2278//C
2279//C       the mapped values [-776,-1] and [-13276,-778] are not used
2280//C
2281//C       I4max should be 2768499, this value will maps to -32768
2282//C       and mantissa should be compared  using
2283//C               IF (R4 .GE. IPW)
2284//C       instead of
2285//C               IF (R4 .GT. (IPW - 1.0))
2286//C
2287//
2288//
2289//C       I4      :       input I*4
2290//C       R4      :       temperory real number storage
2291//C       IPW     :       IPW = IB ** ND
2292//C       NPW     :       number of power
2293//C       IB      :       Base value
2294//C       ND      :       Number of precision digits
2295//C       I4max   :       max data value w/ some error
2296//C       I2max   :       max data value w/o error
2297//C       Error   :       when data value > I4max
2298//C
2299//        INTEGER*4       I4
2300//        INTEGER*4       NPW
2301//        REAL*4          R4
2302//        INTEGER*4       IPW
2303//        INTEGER*4       IB      /10/
2304//        INTEGER*4       ND      /4/
2305//        INTEGER*4       I4max   /2767000/
2306//        INTEGER*4       I2max   /32767/
2307//        INTEGER*4       Error   /-777/
2308//
2309Function CompressI4toI2(i4)
2310        Variable i4
2311
2312        Variable npw,ipw,ib,nd,i4max,i2max,error,i4toi2
2313        Variable r4
2314       
2315        ib=10
2316        nd=4
2317        i4max=2767000
2318        i2max=32767
2319        error=-777
2320       
2321        if(i4 <= i4max)
2322                r4=i4
2323                if(r4 > i2max)
2324                        ipw = ib^nd
2325                        npw=0
2326                        do
2327                                if( !(r4 > (ipw-1)) )           //to simulate a do-while loop evaluating at top
2328                                        break
2329                                endif
2330                                npw=npw+1
2331                                r4=r4/ib               
2332                        while (1)
2333                        i4toi2 = -1*trunc(r4+ipw*npw)
2334                else
2335                        i4toi2 = trunc(r4)              //shouldn't I just return i4 (as a 2 byte value?)
2336                endif
2337        else
2338                i4toi2=error
2339        endif
2340        return(i4toi2)
2341End
2342
2343
2344// function to fill the extra bits of header information to make a "complete"
2345// simulated VAX data file.
2346//
2347//
2348Function SimulationVAXHeader(folder)
2349        String folder
2350
2351        Wave rw=root:Packages:NIST:SAS:realsRead
2352        Wave iw=root:Packages:NIST:SAS:integersRead
2353        Wave/T tw=root:Packages:NIST:SAS:textRead
2354        Wave res=root:Packages:NIST:SAS:results
2355       
2356// integers needed:
2357        //[2] count time
2358        NVAR ctTime = root:Packages:NIST:SAS:gCntTime
2359        iw[2] = ctTime
2360       
2361//reals are partially set in SASCALC initializtion
2362        //remaining values are updated automatically as SASCALC is modified
2363        // -- but still need:
2364        //      [0] monitor count
2365        //      [2] detector count (w/o beamstop)
2366        //      [4] transmission
2367        //      [5] thickness (in cm)
2368        NVAR imon = root:Packages:NIST:SAS:gImon
2369        rw[0] = imon
2370        rw[2] = res[9]
2371        rw[4] = res[8]
2372        NVAR thick = root:Packages:NIST:SAS:gThick
2373        rw[5] = thick
2374       
2375// text values needed:
2376// be sure they are padded to the correct length
2377        // [0] filename (do I fake a VAX name? probably yes...)
2378        // [1] date/time in VAX format
2379        // [2] type (use SIM)
2380        // [3] def dir (use [NG7SANS99])
2381        // [4] mode? C
2382        // [5] reserve (another date), prob not needed
2383        // [6] sample label
2384        // [9] det type "ORNL  " (6 chars)
2385       
2386        tw[1] = "01-JAN-2009 12:12:12"
2387        tw[2] = "SIM"
2388        tw[3] = "[NG7SANS99]"
2389        tw[4] = "C"
2390        tw[5] = "01JAN09 "
2391        tw[9] = "ORNL  "
2392       
2393        NVAR index = root:Packages:NIST:SAS:gSaveIndex
2394        SVAR prefix = root:Packages:NIST:SAS:gSavePrefix
2395
2396        tw[0] = prefix+num2str(index)+".SA2_SIM_A"+num2str(index)
2397        index += 1
2398       
2399        String labelStr=" "     
2400        Prompt labelStr, "Enter sample label "          // Set prompt for x param
2401        DoPrompt "Enter sample label", labelStr
2402        if (V_Flag)
2403                //Print "no sample label entered - no file written"
2404                index -=1
2405                return -1                                                               // User canceled
2406        endif
2407       
2408        labelStr = PadString(labelStr,60,0x20)  //60 fortran-style spaces
2409        tw[6] = labelStr[0,59]
2410       
2411        return(0)
2412End
2413
2414Function ExamineHeader(type)
2415        String type
2416
2417        String data_folder = type
2418        String dataPath = "root:Packages:NIST:"+data_folder
2419        String cur_folder = "ExamineHeader"
2420        String curPath = "root:Packages:NIST:"+cur_folder
2421       
2422        //SetDataFolder curPath
2423
2424        Wave intw=$(dataPath+":IntegersRead")
2425        Wave realw=$(dataPath+":RealsRead")
2426        Wave/T textw=$(dataPath+":TextRead")
2427        Wave logw=$(dataPath+":LogicalsRead")
2428
2429
2430        print "----------------------------------"
2431        print "Header Details"
2432        print "----------------------------------"
2433        print "fname :\t\t"+textw[0]
2434        //
2435        print "run.npre :\t\t"+num2str(intw[0])
2436        print "run.ctime :\t\t"+num2str(intw[1])
2437        print "run.rtime :\t\t"+num2str(intw[2])
2438        print "run.numruns :\t\t"+num2str(intw[3])
2439        //
2440        print "run.moncnt :\t\t"+num2str(realw[0])
2441        print "run.savmon :\t\t"+num2str(realw[1])
2442        print "run.detcnt :\t\t"+num2str(realw[2])
2443        print "run.atten :\t\t"+num2str(realw[3])       
2444        //
2445        print "run.timdat:\t\t"+textw[1]
2446        print "run.type:\t\t"+textw[2]
2447        print "run.defdir:\t\t"+textw[3]
2448        print "run.mode:\t\t"+textw[4]
2449        print "run.reserve:\t\t"+textw[5]
2450        print "sample.labl:\t\t"+textw[6]
2451        //
2452        print "sample.trns:\t\t"+num2str(realw[4])
2453        print "sample.thk:\t\t"+num2str(realw[5])
2454        print "sample.position:\t\t"+num2str(realw[6])
2455        print "sample.rotang:\t\t"+num2str(realw[7])
2456        //
2457        print "sample.table:\t\t"+num2str(intw[4])
2458        print "sample.holder:\t\t"+num2str(intw[5])
2459        print "sample.blank:\t\t"+num2str(intw[6])
2460        //
2461        print "sample.temp:\t\t"+num2str(realw[8])
2462        print "sample.field:\t\t"+num2str(realw[9])     
2463        //
2464        print "sample.tctrlr:\t\t"+num2str(intw[7])
2465        print "sample.magnet:\t\t"+num2str(intw[8])
2466        //
2467        print "sample.tunits:\t\t"+textw[7]
2468        print "sample.funits:\t\t"+textw[8]
2469        print "det.typ:\t\t"+textw[9]
2470        //
2471        print "det.calx(1):\t\t"+num2str(realw[10])
2472        print "det.calx(2):\t\t"+num2str(realw[11])
2473        print "det.calx(3):\t\t"+num2str(realw[12])
2474        print "det.caly(1):\t\t"+num2str(realw[13])
2475        print "det.caly(2):\t\t"+num2str(realw[14])
2476        print "det.caly(3):\t\t"+num2str(realw[15])
2477        //
2478        print "det.num:\t\t"+num2str(intw[9])
2479        print "det.spacer:\t\t"+num2str(intw[10])
2480        //
2481        print "det.beamx:\t\t"+num2str(realw[16])
2482        print "det.beamy:\t\t"+num2str(realw[17])
2483        print "det.dis:\t\t"+num2str(realw[18])
2484        print "det.offset:\t\t"+num2str(realw[19])
2485        print "det.siz:\t\t"+num2str(realw[20])
2486        print "det.bstop:\t\t"+num2str(realw[21])
2487        print "det.blank:\t\t"+num2str(realw[22])
2488        print "resolution.ap1:\t\t"+num2str(realw[23])
2489        print "resolution.ap2:\t\t"+num2str(realw[24])
2490        print "resolution.ap12dis:\t\t"+num2str(realw[25])
2491        print "resolution.lmda:\t\t"+num2str(realw[26])
2492        print "resolution.dlmda:\t\t"+num2str(realw[27])
2493        print "resolution.nlenses:\t\t"+num2str(realw[28])     
2494        //
2495        print "tslice.slicing:\t\t"+num2str(logw[0])
2496        //
2497        print "tslice.multfact:\t\t"+num2str(intw[11])
2498        print "tslice.ltslice:\t\t"+num2str(intw[12])
2499        //
2500        print "temp.printemp:\t\t"+num2str(logw[1])
2501        //
2502        print "temp.hold:\t\t"+num2str(realw[29])
2503        print "temp.err:\t\t"+num2str(realw[30])
2504        print "temp.blank:\t\t"+num2str(realw[31])
2505        //
2506        print "temp.extra:\t\t"+num2str(intw[13])
2507        print "temp.err:\t\t"+num2str(intw[14])
2508        //
2509        print "magnet.printmag:\t\t"+num2str(logw[2])
2510        print "magnet.sensor:\t\t"+num2str(logw[3])
2511        //
2512        print "magnet.current:\t\t"+num2str(realw[32])
2513        print "magnet.conv:\t\t"+num2str(realw[33])
2514        print "magnet.fieldlast:\t\t"+num2str(realw[34])
2515        print "magnet.blank:\t\t"+num2str(realw[35])
2516        print "magnet.spacer:\t\t"+num2str(realw[36])
2517        print "bmstp.xpos:\t\t"+num2str(realw[37])
2518        print "bmstop.ypos:\t\t"+num2str(realw[38])
2519        //     
2520        print "params.blank1:\t\t"+num2str(intw[15])
2521        print "params.blank2:\t\t"+num2str(intw[16])
2522        print "params.blank3:\t\t"+num2str(intw[17])
2523        //
2524        print "params.trnscnt:\t\t"+num2str(realw[39])
2525        print "params.extra1:\t\t"+num2str(realw[40])
2526        print "params.extra2:\t\t"+num2str(realw[41])
2527        print "params.extra3:\t\t"+num2str(realw[42])
2528        //     
2529        print "params.reserve:\t\t"+textw[10]
2530        //
2531        print "voltage.printemp:\t\t"+num2str(logw[4])
2532        //
2533        print "voltage.volts:\t\t"+num2str(realw[43])
2534        print "voltage.blank:\t\t"+num2str(realw[44])
2535        //     
2536        print "voltage.spacer:\t\t"+num2str(intw[18])
2537        //
2538        print "polarization.printpol:\t\t"+num2str(logw[5])
2539        print "polarization.flipper:\t\t"+num2str(logw[6])
2540        //     
2541        print "polarization.horiz:\t\t"+num2str(realw[45])
2542        print "polarization.vert:\t\t"+num2str(realw[46])
2543        //
2544        print "analysis.rows(1):\t\t"+num2str(intw[19])
2545        print "analysis.rows(2):\t\t"+num2str(intw[20])
2546        print "analysis.cols(1):\t\t"+num2str(intw[21])
2547        print "analysis.cols(2):\t\t"+num2str(intw[22])
2548        //
2549        print "analysis.factor:\t\t"+num2str(realw[47])
2550        print "analysis.qmin:\t\t"+num2str(realw[48])
2551        print "analysis.qmax:\t\t"+num2str(realw[49])
2552        print "analysis.imin:\t\t"+num2str(realw[50])
2553        print "analysis.imax:\t\t"+num2str(realw[51])
2554
2555End
2556
2557
2558// Sept 2009 -SRK
2559// the ICE instrument control software is not correctly writing out the file name to the header in the specific
2560// case of a file prefix less than 5 characters. ICE is quite naturally putting the blanke space(s) at the end of
2561// the string. However, the VAX puts them at the beginning...
2562Proc PatchFileNameInHeader(firstFile,lastFile)
2563        Variable firstFile=1,lastFile=100
2564
2565        fPatchFileName(firstFile,lastFile)
2566
2567End
2568
2569Proc ReadFileNameInHeader(firstFile,lastFile)
2570        Variable firstFile=1,lastFile=100
2571       
2572        fReadFileName(firstFile,lastFile)
2573End
2574
2575
2576// simple utility to patch the file name in the file headers
2577// lo is the first file number
2578// hi is the last file number (inclusive)
2579//
2580// will read the 21 character file name and put any spaces at the front of the string
2581// like the VAX does. Should have absolutely no effect if there are spaces at the
2582// beginning of the string, as the VAX does.
2583Function fPatchFileName(lo,hi)
2584        Variable lo,hi
2585       
2586        Variable ii
2587        String file,fileName
2588       
2589        //loop over all files
2590        for(ii=lo;ii<=hi;ii+=1)
2591                file = FindFileFromRunNumber(ii)
2592                if(strlen(file) != 0)
2593                        fileName = getFileName(file)
2594                        WriteFileNameToHeader(file,fileName)
2595                else
2596                        printf "run number %d not found\r",ii
2597                endif
2598        endfor
2599       
2600        return(0)
2601End
2602
2603// simple utility to read the file name stored in the file header (and the suffix)
2604Function fReadFileName(lo,hi)
2605        Variable lo,hi
2606       
2607        String file,fileName,suffix
2608        Variable ii
2609       
2610        for(ii=lo;ii<=hi;ii+=1)
2611                file = FindFileFromRunNumber(ii)
2612                if(strlen(file) != 0)
2613                        fileName = getFileName(file)
2614                        suffix = getSuffix(file)
2615                        printf "File %d:  File name = %s\t\tSuffix = %s\r",ii,fileName,suffix
2616                else
2617                        printf "run number %d not found\r",ii
2618                endif
2619        endfor
2620       
2621        return(0)
2622End
2623
2624
2625
2626
2627// April 2009 - AJJ
2628// The new ICE instrument control software was not correctly writing the run.defdir field
2629// The format of that field should be [NGxSANSn] where x is 3 or 7 and nn is 0 through 50
2630
2631Proc PatchUserAccountName(firstFile,lastFile,acctName)
2632        Variable firstFile=1,lastFile=100
2633        String acctName = "NG3SANS0"
2634
2635        fPatchUserAccountName(firstFile,lastFile,acctName)
2636
2637End
2638
2639Proc ReadUserAccountName(firstFile,lastFile)
2640        Variable firstFile=1,lastFile=100
2641       
2642        fReadUserAccountName(firstFile,lastFile)
2643End
2644
2645// simple utility to patch the user account name in the file headers
2646// pass in the account name as a string
2647// lo is the first file number
2648// hi is the last file number (inclusive)
2649//
2650Function fPatchUserAccountName(lo,hi,acctName)
2651        Variable lo,hi
2652        String acctName
2653       
2654        Variable ii
2655        String file
2656       
2657        //loop over all files
2658        for(ii=lo;ii<=hi;ii+=1)
2659                file = FindFileFromRunNumber(ii)
2660                if(strlen(file) != 0)
2661                        WriteAcctNameToHeader(file,acctName)
2662                else
2663                        printf "run number %d not found\r",ii
2664                endif
2665        endfor
2666       
2667        return(0)
2668End
2669
2670// simple utility to read the user account name stored in the file header
2671Function fReadUserAccountName(lo,hi)
2672        Variable lo,hi
2673       
2674        String file,acctName
2675        Variable ii
2676       
2677        for(ii=lo;ii<=hi;ii+=1)
2678                file = FindFileFromRunNumber(ii)
2679                if(strlen(file) != 0)
2680                        acctName = getAcctName(file)
2681                        printf "File %d:  Account name = %s\r",ii,acctName
2682                else
2683                        printf "run number %d not found\r",ii
2684                endif
2685        endfor
2686       
2687        return(0)
2688End
2689
2690// May 2009 - SRK
2691// Monitor count not written correctly to file from ICE
2692
2693Proc PatchMonitorCount(firstFile,lastFile,monCtRate)
2694        Variable firstFile=1,lastFile=100,monCtRate
2695
2696        fPatchMonitorCount(firstFile,lastFile,monCtRate)
2697
2698End
2699
2700Proc ReadMonitorCount(firstFile,lastFile)
2701        Variable firstFile=1,lastFile=100
2702       
2703        fReadMonitorCount(firstFile,lastFile)
2704End
2705
2706// simple utility to patch the user account name in the file headers
2707// pass in the account name as a string
2708// lo is the first file number
2709// hi is the last file number (inclusive)
2710//
2711Function fPatchMonitorCount(lo,hi,monCtRate)
2712        Variable lo,hi,monCtRate
2713       
2714        Variable ii,ctTime
2715        String file
2716       
2717        //loop over all files
2718        for(ii=lo;ii<=hi;ii+=1)
2719                file = FindFileFromRunNumber(ii)
2720                if(strlen(file) != 0)
2721                        ctTime = getCountTime(file)
2722                        WriteMonitorCountToHeader(file,ctTime*monCtRate)                       
2723                else
2724                        printf "run number %d not found\r",ii
2725                endif
2726        endfor
2727       
2728        return(0)
2729End
2730
2731// simple utility to read the user account name stored in the file header
2732Function fReadMonitorCount(lo,hi)
2733        Variable lo,hi
2734       
2735        String file
2736        Variable ii,monitorCount
2737       
2738        for(ii=lo;ii<=hi;ii+=1)
2739                file = FindFileFromRunNumber(ii)
2740                if(strlen(file) != 0)
2741                        monitorCount = getMonitorCount(file)
2742                        printf "File %d:  Monitor Count = %g\r",ii,monitorCount
2743                else
2744                        printf "run number %d not found\r",ii
2745                endif
2746        endfor
2747       
2748        return(0)
2749End
2750
2751
2752/////
2753Proc ReadDetectorCount(firstFile,lastFile)
2754        Variable firstFile=1,lastFile=100
2755       
2756        fReadDetectorCount(firstFile,lastFile)
2757End
2758
2759
2760// simple utility to read the detector count from the header, and the summed data value
2761// and print out the values
2762Function fReadDetectorCount(lo,hi)
2763        Variable lo,hi
2764       
2765        String file
2766        Variable ii,summed
2767       
2768        for(ii=lo;ii<=hi;ii+=1)
2769                file = FindFileFromRunNumber(ii)
2770                if(strlen(file) != 0)
2771                        ReadHeaderAndData(file)
2772                        Wave rw=root:Packages:NIST:RAW:RealsRead
2773                        Wave data=root:Packages:NIST:RAW:data                   //data as read in is linear
2774                        summed = sum(data,-inf,inf)
2775                        printf "File %d:  DetCt Header = %g\t Detector Sum = %g\t Ratio sum/hdr = %g\r",ii,rw[2],summed,summed/rw[2]
2776                else
2777                        printf "run number %d not found\r",ii
2778                endif
2779        endfor
2780       
2781        return(0)
2782End
Note: See TracBrowser for help on using the repository browser.