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

Last change on this file since 483 was 483, checked in by ajj, 13 years ago

Adding necessary functions for Live Data and Header printout

File size: 62.2 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       
476        SetDataFolder root:             //(redundant)
477//      Silent 0
478End
479
480
481//this function is the guts of reading a binary VAX file of real (4-byte) values
482// (i.e. a WORK.aaa file)
483// work files have the same header structure as RAW SANS data, just with
484//different data (real, rather than compressed integer data)
485//
486//************
487//this routine incorrectly reads in several data values where the VAX record
488//marker splits the 4-byte real (at alternating record markers)
489//this error seems to not be severe, but shoud be corrected (at great pain)
490//************
491//
492// called from ProtocolAsPanel.ipf
493//
494//
495Function ReadHeaderAndWork(type,fname)
496        String type,fname
497       
498        //type is the desired folder to read the workfile to
499        //this data will NOT be automatically displayed gDataDisplayType is unchanged
500
501//      SVAR cur_folder=root:myGlobals:gDataDisplayType
502        String cur_folder = type
503        String curPath = "root:Packages:NIST:"+cur_folder
504        SetDataFolder curPath           //use the full path, so it will always work
505       
506        Variable refNum,integer,realval
507        String sansfname,textstr
508        Variable/G $(curPath + ":gIsLogScale") = 0              //initial state is linear, keep this in DIV folder
509       
510        Make/O/N=23 $(curPath + ":IntegersRead")
511        Make/O/N=52 $(curPath + ":RealsRead")
512        Make/O/T/N=11 $(curPath + ":TextRead")
513       
514        WAVE intw=$(curPath + ":IntegersRead")
515        WAVE realw=$(curPath + ":RealsRead")
516        WAVE/T textw=$(curPath + ":TextRead")
517       
518        //***NOTE ****
519        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
520        // this read routine, after the open dialog is presented
521        // the "--read" waves end up in the correct folder, but the data does not! Why?
522        //must re-set data folder before writing data array (done below)
523       
524        SetDataFolder curPath
525       
526        //actually open the file
527        Open/R refNum as fname
528        //skip first two bytes
529        FSetPos refNum, 2
530        //read the next 21 bytes as characters (fname)
531        FReadLine/N=21 refNum,textstr
532        textw[0]= textstr
533        //read four i*4 values  /F=3 flag, B=3 flag
534        FBinRead/F=3/B=3 refNum, integer
535        intw[0] = integer
536        //
537        FBinRead/F=3/B=3 refNum, integer
538        intw[1] = integer
539        //
540        FBinRead/F=3/B=3 refNum, integer
541        intw[2] = integer
542        //
543        FBinRead/F=3/B=3 refNum, integer
544        intw[3] = integer
545        // 6 text fields
546        FSetPos refNum,55               //will start reading at byte 56
547        FReadLine/N=20 refNum,textstr
548        textw[1]= textstr
549        FReadLine/N=3 refNum,textstr
550        textw[2]= textstr
551        FReadLine/N=11 refNum,textstr
552        textw[3]= textstr
553        FReadLine/N=1 refNum,textstr
554        textw[4]= textstr
555        FReadLine/N=8 refNum,textstr
556        textw[5]= textstr
557        FReadLine/N=60 refNum,textstr
558        textw[6]= textstr
559       
560        //3 integers
561        FSetPos refNum,174
562        FBinRead/F=3/B=3 refNum, integer
563        intw[4] = integer
564        FBinRead/F=3/B=3 refNum, integer
565        intw[5] = integer
566        FBinRead/F=3/B=3 refNum, integer
567        intw[6] = integer
568       
569        //2 integers, 3 text fields
570        FSetPos refNum,194
571        FBinRead/F=3/B=3 refNum, integer
572        intw[7] = integer
573        FBinRead/F=3/B=3 refNum, integer
574        intw[8] = integer
575        FReadLine/N=6 refNum,textstr
576        textw[7]= textstr
577        FReadLine/N=6 refNum,textstr
578        textw[8]= textstr
579        FReadLine/N=6 refNum,textstr
580        textw[9]= textstr
581       
582        //2 integers
583        FSetPos refNum,244
584        FBinRead/F=3/B=3 refNum, integer
585        intw[9] = integer
586        FBinRead/F=3/B=3 refNum, integer
587        intw[10] = integer
588       
589        //2 integers
590        FSetPos refNum,308
591        FBinRead/F=3/B=3 refNum, integer
592        intw[11] = integer
593        FBinRead/F=3/B=3 refNum, integer
594        intw[12] = integer
595       
596        //2 integers
597        FSetPos refNum,332
598        FBinRead/F=3/B=3 refNum, integer
599        intw[13] = integer
600        FBinRead/F=3/B=3 refNum, integer
601        intw[14] = integer
602       
603        //3 integers
604        FSetPos refNum,376
605        FBinRead/F=3/B=3 refNum, integer
606        intw[15] = integer
607        FBinRead/F=3/B=3 refNum, integer
608        intw[16] = integer
609        FBinRead/F=3/B=3 refNum, integer
610        intw[17] = integer
611       
612        //1 text field - the file association for transmission are the first 4 bytes
613        FSetPos refNum,404
614        FReadLine/N=42 refNum,textstr
615        textw[10]= textstr
616       
617        //1 integer
618        FSetPos refNum,458
619        FBinRead/F=3/B=3 refNum, integer
620        intw[18] = integer
621       
622        //4 integers
623        FSetPos refNum,478
624        FBinRead/F=3/B=3 refNum, integer
625        intw[19] = integer
626        FBinRead/F=3/B=3 refNum, integer
627        intw[20] = integer
628        FBinRead/F=3/B=3 refNum, integer
629        intw[21] = integer
630        FBinRead/F=3/B=3 refNum, integer
631        intw[22] = integer
632       
633        Close refNum
634       
635        //now get all of the reals
636        //
637        //Do all the GBLoadWaves at the end
638        //
639        //FBinRead Cannot handle 32 bit VAX floating point
640        //GBLoadWave, however, can properly read it
641        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
642        String strToExecute
643        //append "/S=offset/U=numofreals" to control the read
644        // then append fname to give the full file path
645        // then execute
646       
647        Variable a=0,b=0
648       
649        SetDataFolder curPath
650        // 4 R*4 values
651        strToExecute = GBLoadStr + "/S=39/U=4" + "\"" + fname + "\""
652        Execute strToExecute
653       
654        SetDataFolder curPath
655        Wave w=$(curPath + ":tempGBWave0")
656        b=4     //num of reals read
657        realw[a,a+b-1] = w[p-a]
658        a+=b
659       
660        // 4 R*4 values
661        SetDataFolder curPath
662        strToExecute = GBLoadStr + "/S=158/U=4" + "\"" + fname + "\""
663        Execute strToExecute
664        b=4     
665        realw[a,a+b-1] = w[p-a]
666        a+=b
667
668///////////
669        // 2 R*4 values
670        SetDataFolder curPath
671        strToExecute = GBLoadStr + "/S=186/U=2" + "\"" + fname + "\""
672        Execute strToExecute
673        b=2     
674        realw[a,a+b-1] = w[p-a]
675        a+=b
676
677        // 6 R*4 values
678        SetDataFolder curPath
679        strToExecute = GBLoadStr + "/S=220/U=6" + "\"" + fname + "\""
680        Execute strToExecute
681        b=6     
682        realw[a,a+b-1] = w[p-a]
683        a+=b
684       
685        // 13 R*4 values
686        SetDataFolder curPath
687        strToExecute = GBLoadStr + "/S=252/U=13" + "\"" + fname + "\""
688        Execute strToExecute
689        b=13
690        realw[a,a+b-1] = w[p-a]
691        a+=b
692       
693        // 3 R*4 values
694        SetDataFolder curPath
695        strToExecute = GBLoadStr + "/S=320/U=3" + "\"" + fname + "\""
696        Execute strToExecute
697        b=3     
698        realw[a,a+b-1] = w[p-a]
699        a+=b
700       
701        // 7 R*4 values
702        SetDataFolder curPath
703        strToExecute = GBLoadStr + "/S=348/U=7" + "\"" + fname + "\""
704        Execute strToExecute
705        b=7
706        realw[a,a+b-1] = w[p-a]
707        a+=b
708       
709        // 4 R*4 values
710        SetDataFolder curPath
711        strToExecute = GBLoadStr + "/S=388/U=4" + "\"" + fname + "\""
712        Execute strToExecute
713        b=4     
714        realw[a,a+b-1] = w[p-a]
715        a+=b
716       
717        // 2 R*4 values
718        SetDataFolder curPath
719        strToExecute = GBLoadStr + "/S=450/U=2" + "\"" + fname + "\""
720        Execute strToExecute
721        b=2
722        realw[a,a+b-1] = w[p-a]
723        a+=b
724       
725        // 2 R*4 values
726        SetDataFolder curPath
727        strToExecute = GBLoadStr + "/S=470/U=2" + "\"" + fname + "\""
728        Execute strToExecute
729        b=2
730        realw[a,a+b-1] = w[p-a]
731        a+=b
732       
733        // 5 R*4 values
734        SetDataFolder curPath
735        strToExecute = GBLoadStr + "/S=494/U=5" + "\"" + fname + "\""
736        Execute strToExecute
737        b=5     
738        realw[a,a+b-1] = w[p-a]
739       
740        //if the binary VAX data ws transferred to a MAC, all is OK
741        //if the data was trasnferred to an Intel machine (IBM), all the real values must be
742        //divided by 4 to get the correct floating point values
743        // I can't find any combination of settings in GBLoadWave or FBinRead to read data in correctly
744        // on an Intel machine.
745        //With the corrected version of GBLoadWave XOP (v. 1.43 or higher) Mac and PC both read
746        //VAX reals correctly, and no checking is necessary 12 APR 99
747        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
748                //do nothing
749        //else
750                //either Windows or Windows NT
751                //realw /= 4
752        //endif
753       
754        //read in the data
755         GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
756
757        curPath = "root:Packages:NIST:"+cur_folder
758        SetDataFolder curPath           //use the full path, so it will always work
759       
760        Make/O/N=16384 $(curPath + ":data")
761        WAVE data = $(curPath + ":data")
762       
763        Variable skip,ii,offset
764       
765        //read in a total of 16384 values (ii)
766        //as follows :
767        // skip first 2 bytes
768        // skip 512 byte header
769        // skip first 2 bytes of data
770        //(read 511 reals, skip 2b, 510 reals, skip 2b) -16 times = 16336 values
771        // read the final 48 values in seperately to avoid EOF error
772       
773        /////////////
774        SetDataFolder curPath
775        skip = 0
776        ii=0
777        offset = 514 +2
778        a=0
779        do
780                SetDataFolder curPath
781               
782                strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=511" + "\"" + fname + "\""
783                Execute strToExecute
784                //Print strToExecute
785                b=511
786                data[a,a+b-1] = w[p-a]
787                a+=b
788               
789                offset += 511*4 +2
790               
791                strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=510" + "\"" + fname + "\""
792                SetDataFolder curPath
793                Execute strToExecute
794                //Print strToExecute
795                b=510
796                data[a,a+b-1] = w[p-a]
797                a+=b
798               
799                offset += 510*4 +2
800               
801                ii+=1
802                //Print "inside do, data[2] =",data[2]
803                //Print "inside do, tempGBwave0[0] = ",w[0]
804        while(ii<16)
805       
806        // 16336 values have been read in --
807        //read in last 64 values
808        strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=48" + "\"" + fname + "\""
809       
810        SetDataFolder curPath
811        Execute strToExecute
812        b=48
813        data[a,a+b-1] = w[p-a]
814        a+=b
815//
816/// done reading in raw data
817//
818        //Print "in workdatareader , data = ", data[1][1]
819
820        Redimension/n=(128,128) data
821       
822        //clean up - get rid of w = $"tempGBWave0"
823        KillWaves w
824       
825        //divide the FP data by 4 if read from a PC (not since GBLoadWave update)
826        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
827                //do nothing
828        //else
829                //either Windows or Windows NT
830                //data /= 4
831        //endif
832       
833        //keep a string with the filename in the DIV folder
834        String/G $(curPath + ":fileList") = textw[0]
835       
836        //return the data folder to root
837        SetDataFolder root:
838       
839        Return(0)
840End
841
842/////   ASC FORMAT READER  //////
843/////   FOR WORKFILE MATH PANEL //////
844
845//function to read in the ASC output of SANS reduction
846// currently the file has 20 header lines, followed by a single column
847// of 16384 values, Data is written by row, starting with Y=1 and X=(1->128)
848//
849//returns 0 if read was ok
850//returns 1 if there was an error
851//
852// called by WorkFileUtils.ipf
853//
854Function ReadASCData(fname,destPath)
855        String fname, destPath
856        //this function is for reading in ASCII data so put data in user-specified folder
857        SetDataFolder "root:Packages:NIST:"+destPath
858
859        NVAR pixelsX = root:myGlobals:gNPixelsX
860        NVAR pixelsY = root:myGlobals:gNPixelsY
861        Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20
862        String str=""
863        //data is initially linear scale
864        Variable/G :gIsLogScale=0
865        Make/O/T/N=(numHdrLines) hdrLines
866        Make/O/D/N=(pixelsX*pixelsY) data                       //,linear_data
867       
868        //full filename and path is now passed in...
869        //actually open the file
870//      SetDataFolder destPath
871        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
872        if(refnum==0)           //FNF error, get out
873                DoAlert 0,"Could not find file: "+fname
874                Close/A
875                SetDataFolder root:
876                return(1)
877        endif
878        if(V_flag!=0)
879                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
880                Close/A
881                SetDataFolder root:
882                return(1)
883        Endif
884        //
885        for(ii=0;ii<numHdrLines;ii+=1)          //read (or skip) 18 header lines
886                FReadLine refnum,str
887                hdrLines[ii]=str
888        endfor
889        //     
890        Close refnum
891       
892//      SetDataFolder destPath
893        LoadWave/Q/G/D/N=temp fName
894        Wave/Z temp0=temp0
895        data=temp0
896        Redimension/N=(pixelsX,pixelsY) data            //,linear_data
897       
898        //linear_data = data
899       
900        KillWaves/Z temp0
901       
902        //return the data folder to root
903        SetDataFolder root:
904       
905        Return(0)
906End
907
908// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
909// pay attention to what is/not to be trusted due to "fake" information.
910// uses what it can from the header lines from the ASC file (hdrLines wave)
911//
912// destFolder is of the form "myGlobals:WorkMath:AAA"
913//
914//
915// called by WorkFileUtils.ipf
916//
917Function FillFakeHeader_ASC(destFolder)
918        String destFolder
919        Make/O/N=23 $("root:Packages:NIST:"+destFolder+":IntegersRead")
920        Make/O/N=52 $("root:Packages:NIST:"+destFolder+":RealsRead")
921        Make/O/T/N=11 $("root:Packages:NIST:"+destFolder+":TextRead")
922       
923        Wave intw=$("root:Packages:NIST:"+destFolder+":IntegersRead")
924        Wave realw=$("root:Packages:NIST:"+destFolder+":RealsRead")
925        Wave/T textw=$("root:Packages:NIST:"+destFolder+":TextRead")
926       
927        //Put in appropriate "fake" values
928        //parse values as needed from headerLines
929        Wave/T hdr=$("root:Packages:NIST:"+destFolder+":hdrLines")
930        Variable monCt,lam,offset,sdd,trans,thick
931        Variable xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam
932        String detTyp=""
933        String tempStr="",formatStr="",junkStr=""
934        formatStr = "%g %g %g %g %g %g"
935        tempStr=hdr[3]
936        sscanf tempStr, formatStr, monCt,lam,offset,sdd,trans,thick
937//      Print monCt,lam,offset,sdd,trans,thick,avStr,step
938        formatStr = "%g %g %g %g %g %g %g %s"
939        tempStr=hdr[5]
940        sscanf tempStr,formatStr,xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
941//      Print xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
942       
943        realw[16]=xCtr          //xCtr(pixels)
944        realw[17]=yCtr  //yCtr (pixels)
945        realw[18]=sdd           //SDD (m)
946        realw[26]=lam           //wavelength (A)
947        //
948        // necessary values
949        realw[10]=5                     //detector calibration constants, needed for averaging
950        realw[11]=10000
951        realw[12]=0
952        realw[13]=5
953        realw[14]=10000
954        realw[15]=0
955        //
956        // used in the resolution calculation, ONLY here to keep the routine from crashing
957        realw[20]=65            //det size
958        realw[27]=dlam  //delta lambda
959        realw[21]=bsDiam        //BS size
960        realw[23]=a1            //A1
961        realw[24]=a2    //A2
962        realw[25]=a1a2Dist      //A1A2 distance
963        realw[4]=trans          //trans
964        realw[3]=0              //atten
965        realw[5]=thick          //thick
966        //
967        //
968        realw[0]=monCt          //def mon cts
969
970        // fake values to get valid deadtime and detector constants
971        //
972        textw[9]=detTyp+"  "            //6 characters 4+2 spaces
973        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
974       
975        //set the string values
976        formatStr="FILE: %s CREATED: %s"
977        sscanf hdr[0],formatStr,tempStr,junkStr
978//      Print tempStr
979//      Print junkStr
980        String/G $("root:Packages:NIST:"+destFolder+":fileList") = tempStr
981        textw[0] = tempStr              //filename
982        textw[1] = junkStr              //run date-time
983       
984        //file label = hdr[1]
985        tempStr = hdr[1]
986        tempStr = tempStr[0,strlen(tempStr)-2]          //clean off the last LF
987//      Print tempStr
988        textW[6] = tempStr      //sample label
989       
990        return(0)
991End
992
993
994/////*****************
995////unused testing procedure for writing a 4 byte floating point value in VAX format
996//Proc TestReWriteReal()
997//      String Path
998//      Variable value,start
999//     
1000//      GetFileAndPath()
1001//      Path = S_Path + S_filename
1002//     
1003//      value = 0.2222
1004//      start = 158             //trans starts at byte 159
1005//      ReWriteReal(path,value,start)
1006//     
1007//      SetDataFolder root:
1008//End
1009
1010//function will re-write a real value (4bytes) to the header of a RAW data file
1011//to ensure re-readability, the real value must be written mimicking VAX binary format
1012//which is done in this function
1013//path is the full path:file;vers to the file
1014//value is the real value to write
1015//start is the position to move the file marker to, to begin writing
1016//--so start is actually the "end byte" of the previous value
1017//
1018// Igor cannot write VAX FP values - so to "fake it"
1019// (1) write IEEE FP, 4*desired value, little endian
1020// (2) read back as two 16-bit integers, big endian
1021// (3) write the two 16-bit integers, reversed, writing each as big endian
1022//
1023//this procedure takes care of all file open/close pairs needed
1024//
1025Function WriteVAXReal(path,value,start)
1026        String path
1027        Variable value,start
1028       
1029        //Print " in F(), path = " + path
1030        Variable refnum,int1,int2, value4
1031
1032//////
1033        value4 = 4*value
1034       
1035        Open/A/T="????TEXT" refnum as path
1036        //write IEEE FP, 4*desired value
1037        FSetPos refnum,start
1038        FBinWrite/B=3/F=4 refnum,value4         //write out as little endian
1039        //move to the end of the file
1040        FStatus refnum
1041        FSetPos refnum,V_logEOF
1042        Close refnum
1043       
1044///////
1045        Open/R refnum as path
1046        //read back as two 16-bit integers
1047        FSetPos refnum,start
1048        FBinRead/B=2/F=2 refnum,int1    //read as big-endian
1049        FBinRead/B=2/F=2 refnum,int2   
1050        //file was opened read-only, no need to move to the end of the file, just close it     
1051        Close refnum
1052       
1053///////
1054        Open/A/T="????TEXT" refnum as path
1055        //write the two 16-bit integers, reversed
1056        FSetPos refnum,start
1057        FBinWrite/B=2/F=2 refnum,int2   //re-write as big endian
1058        FBinWrite/B=2/F=2 refnum,int1
1059        //move to the end of the file
1060        FStatus refnum
1061        FSetPos refnum,V_logEOF
1062        Close refnum            //at this point, it is as the VAX would have written it.
1063       
1064        Return(0)
1065End
1066
1067//sample transmission is a real value at byte 158
1068Function WriteTransmissionToHeader(fname,trans)
1069        String fname
1070        Variable trans
1071       
1072        WriteVAXReal(fname,trans,158)           //transmission start byte is 158
1073        return(0)
1074End
1075
1076//whole transmission is a real value at byte 392
1077Function WriteWholeTransToHeader(fname,trans)
1078        String fname
1079        Variable trans
1080       
1081        WriteVAXReal(fname,trans,392)           //transmission start byte is 392
1082        return(0)
1083End
1084
1085//box sum counts is a real value at byte 494
1086Function WriteBoxCountsToHeader(fname,counts)
1087        String fname
1088        Variable counts
1089       
1090        WriteVAXReal(fname,counts,494)          // start byte is 494
1091        return(0)
1092End
1093
1094//beam stop X-pos is at byte 368
1095Function WriteBSXPosToHeader(fname,xpos)
1096        String fname
1097        Variable xpos
1098       
1099        WriteVAXReal(fname,xpos,368)
1100        return(0)
1101End
1102
1103//sample thickness is at byte 162
1104Function WriteThicknessToHeader(fname,num)
1105        String fname
1106        Variable num
1107       
1108        WriteVAXReal(fname,num,162)
1109        return(0)
1110End
1111
1112//beam center X pixel location is at byte 252
1113Function WriteBeamCenterXToHeader(fname,num)
1114        String fname
1115        Variable num
1116       
1117        WriteVAXReal(fname,num,252)
1118        return(0)
1119End
1120
1121//beam center Y pixel location is at byte 256
1122Function WriteBeamCenterYToHeader(fname,num)
1123        String fname
1124        Variable num
1125       
1126        WriteVAXReal(fname,num,256)
1127        return(0)
1128End
1129
1130//attenuator number (not its transmission) is at byte 51
1131Function WriteAttenNumberToHeader(fname,num)
1132        String fname
1133        Variable num
1134       
1135        WriteVAXReal(fname,num,51)
1136        return(0)
1137End
1138
1139//monitor count is at byte 39
1140Function WriteMonitorCountToHeader(fname,num)
1141        String fname
1142        Variable num
1143       
1144        WriteVAXReal(fname,num,39)
1145        return(0)
1146End
1147
1148//total detector count is at byte 47
1149Function WriteDetectorCountToHeader(fname,num)
1150        String fname
1151        Variable num
1152       
1153        WriteVAXReal(fname,num,47)
1154        return(0)
1155End
1156
1157//transmission detector count is at byte 388
1158Function WriteTransDetCountToHeader(fname,num)
1159        String fname
1160        Variable num
1161       
1162        WriteVAXReal(fname,num,388)
1163        return(0)
1164End
1165
1166//wavelength is at byte 292
1167Function WriteWavelengthToHeader(fname,num)
1168        String fname
1169        Variable num
1170       
1171        WriteVAXReal(fname,num,292)
1172        return(0)
1173End
1174
1175//wavelength spread is at byte 296
1176Function WriteWavelengthDistrToHeader(fname,num)
1177        String fname
1178        Variable num
1179       
1180        WriteVAXReal(fname,num,296)
1181        return(0)
1182End
1183
1184//temperature is at byte 186
1185Function WriteTemperatureToHeader(fname,num)
1186        String fname
1187        Variable num
1188       
1189        WriteVAXReal(fname,num,186)
1190        return(0)
1191End
1192
1193//magnetic field is at byte 190
1194Function WriteMagnFieldToHeader(fname,num)
1195        String fname
1196        Variable num
1197       
1198        WriteVAXReal(fname,num,190)
1199        return(0)
1200End
1201
1202//Source Aperture diameter is at byte 280
1203Function WriteSourceApDiamToHeader(fname,num)
1204        String fname
1205        Variable num
1206       
1207        WriteVAXReal(fname,num,280)
1208        return(0)
1209End
1210
1211//Sample Aperture diameter is at byte 284
1212Function WriteSampleApDiamToHeader(fname,num)
1213        String fname
1214        Variable num
1215       
1216        WriteVAXReal(fname,num,284)
1217        return(0)
1218End
1219
1220//Source to sample distance is at byte 288
1221Function WriteSrcToSamDistToHeader(fname,num)
1222        String fname
1223        Variable num
1224       
1225        WriteVAXReal(fname,num,288)
1226        return(0)
1227End
1228
1229//detector offset is at byte 264
1230Function WriteDetectorOffsetToHeader(fname,num)
1231        String fname
1232        Variable num
1233       
1234        WriteVAXReal(fname,num,264)
1235        return(0)
1236End
1237
1238//beam stop diameter is at byte 272
1239Function WriteBeamStopDiamToHeader(fname,num)
1240        String fname
1241        Variable num
1242       
1243        WriteVAXReal(fname,num,272)
1244        return(0)
1245End
1246
1247//sample to detector distance is at byte 260
1248Function WriteSDDToHeader(fname,num)
1249        String fname
1250        Variable num
1251       
1252        WriteVAXReal(fname,num,260)
1253        return(0)
1254End
1255
1256//detector pixel X size (mm) is at byte 220
1257Function WriteDetPixelXToHeader(fname,num)
1258        String fname
1259        Variable num
1260       
1261        WriteVAXReal(fname,num,220)
1262        return(0)
1263End
1264
1265//detector pixel Y size (mm) is at byte 232
1266Function WriteDetPixelYToHeader(fname,num)
1267        String fname
1268        Variable num
1269       
1270        WriteVAXReal(fname,num,232)
1271        return(0)
1272End
1273
1274//rewrite a text field back to the header
1275// fname is the full path:name
1276// str is the CORRECT length - it will all be written - pad or trim before passing
1277// start is the start byte
1278Function WriteTextToHeader(fname,str,start)
1279        String fname,str
1280        Variable start
1281       
1282        Variable refnum
1283        Open/A/T="????TEXT" refnum as fname      //Open for writing! Move to EOF before closing!
1284        FSetPos refnum,start
1285        FBinWrite/F=0 refnum, str      //native object format (character)
1286        //move to the end of the file before closing
1287        FStatus refnum
1288        FSetPos refnum,V_logEOF
1289        Close refnum
1290               
1291        return(0)
1292end
1293
1294// sample label, starts at byte 98
1295// limit to 60 characters
1296Function WriteSamLabelToHeader(fname,str)
1297        String fname,str
1298       
1299        if(strlen(str) > 60)
1300                str = str[0,59]
1301        endif
1302        WriteTextToHeader(fname,str,98)
1303        return(0)
1304End
1305
1306//rewrite an integer field back to the header
1307// fname is the full path:name
1308// val is the integer value
1309// start is the start byte
1310Function RewriteIntegerToHeader(fname,val,start)
1311        String fname
1312        Variable val,start
1313       
1314        Variable refnum
1315        Open/A/T="????TEXT" refnum as fname      //Open for writing! Move to EOF before closing!
1316        FSetPos refnum,start
1317        FBinWrite/B=3/F=3 refnum, val      //write a 4-byte integer
1318        //move to the end of the file before closing
1319        FStatus refnum
1320        FSetPos refnum,V_logEOF
1321        Close refnum
1322               
1323        return(0)
1324end
1325
1326Function WriteCountTimeToHeader(fname,num)
1327        String fname
1328        Variable num
1329       
1330        RewriteIntegerToHeader(fname,num,31)
1331        return(0)
1332End
1333
1334// read specific bits of information from the header
1335// each of these operations MUST take care of open/close on their own
1336
1337Function/S getStringFromHeader(fname,start,num)
1338        String fname                            //full path:name
1339        Variable start,num              //starting byte and number of characters to read
1340       
1341        String str
1342        Variable refnum
1343        Open/R refNum as fname
1344        FSetPos refNum,start
1345        FReadLine/N=(num) refNum,str
1346        Close refnum
1347       
1348        return(str)
1349End
1350
1351// file suffix (4 characters @ byte 19)
1352Function/S getSuffix(fname)
1353        String fname
1354       
1355        return(getStringFromHeader(fname,19,4))
1356End
1357
1358// associated file suffix (for transmission) (4 characters @ byte 404)
1359Function/S getAssociatedFileSuffix(fname)
1360        String fname
1361       
1362        return(getStringFromHeader(fname,404,4))
1363End
1364
1365// sample label (60 characters @ byte 98)
1366Function/S getSampleLabel(fname)
1367        String fname
1368       
1369        return(getStringFromHeader(fname,98,60))
1370End
1371
1372// file creation date (20 characters @ byte 55)
1373Function/S getFileCreationDate(fname)
1374        String fname
1375       
1376        return(getStringFromHeader(fname,55,20))
1377End
1378
1379// read a single real value with GBLoadWave
1380Function getRealValueFromHeader(fname,start)
1381        String fname
1382        Variable start
1383
1384        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
1385       
1386        GBLoadStr += "/S="+num2str(start)+"/U=1" + "\"" + fname + "\""
1387        Execute GBLoadStr
1388        Wave w=$"tempGBWave0"
1389       
1390        return(w[0])
1391End
1392
1393//monitor count is at byte 39
1394Function getMonitorCount(fname)
1395        String fname
1396       
1397        return(getRealValueFromHeader(fname,39))
1398end
1399
1400//saved monitor count is at byte 43
1401Function getSavMon(fname)
1402        String fname
1403       
1404        return(getRealValueFromHeader(fname,43))
1405end
1406
1407//detector count is at byte 47
1408Function getDetCount(fname)
1409        String fname
1410       
1411        return(getRealValueFromHeader(fname,47))
1412end
1413
1414//Attenuator number is at byte 51
1415Function getAttenNumber(fname)
1416        String fname
1417       
1418        return(getRealValueFromHeader(fname,51))
1419end
1420
1421//transmission is at byte 158
1422Function getSampleTrans(fname)
1423        String fname
1424       
1425        return(getRealValueFromHeader(fname,158))
1426end
1427
1428//box counts are stored at byte 494
1429Function getBoxCounts(fname)
1430        String fname
1431       
1432        return(getRealValueFromHeader(fname,494))
1433end
1434
1435//whole detector trasmission is at byte 392
1436Function getSampleTransWholeDetector(fname)
1437        String fname
1438       
1439        return(getRealValueFromHeader(fname,392))
1440end
1441
1442//SampleThickness is at byte 162
1443Function getSampleThickness(fname)
1444        String fname
1445       
1446        return(getRealValueFromHeader(fname,162))
1447end
1448
1449//Sample Rotation Angle is at byte 170
1450Function getSampleRotationAngle(fname)
1451        String fname
1452       
1453        return(getRealValueFromHeader(fname,170))
1454end
1455
1456//temperature is at byte 186
1457Function getTemperature(fname)
1458        String fname
1459       
1460        return(getRealValueFromHeader(fname,186))
1461end
1462
1463//field strength is at byte 190
1464// 190 is not the right location, 348 looks to be correct for the electromagnets, 450 for the
1465// superconducting magnet. Although each place is only the voltage, it is correct
1466Function getFieldStrength(fname)
1467        String fname
1468       
1469//      return(getRealValueFromHeader(fname,190))
1470        return(getRealValueFromHeader(fname,348))
1471end
1472
1473//beam xPos is at byte 252
1474Function getBeamXPos(fname)
1475        String fname
1476       
1477        return(getRealValueFromHeader(fname,252))
1478end
1479
1480//beam Y pos is at byte 256
1481Function getBeamYPos(fname)
1482        String fname
1483       
1484        return(getRealValueFromHeader(fname,256))
1485end
1486
1487//sample to detector distance is at byte 260
1488Function getSDD(fname)
1489        String fname
1490       
1491        return(getRealValueFromHeader(fname,260))
1492end
1493
1494//detector offset is at byte 264
1495Function getDetectorOffset(fname)
1496        String fname
1497       
1498        return(getRealValueFromHeader(fname,264))
1499end
1500
1501//Beamstop diameter is at byte 272
1502Function getBSDiameter(fname)
1503        String fname
1504       
1505        return(getRealValueFromHeader(fname,272))
1506end
1507
1508//source aperture diameter is at byte 280
1509Function getSourceApertureDiam(fname)
1510        String fname
1511       
1512        return(getRealValueFromHeader(fname,280))
1513end
1514
1515//sample aperture diameter is at byte 284
1516Function getSampleApertureDiam(fname)
1517        String fname
1518       
1519        return(getRealValueFromHeader(fname,284))
1520end
1521
1522//source AP to Sample AP distance is at byte 288
1523Function getSourceToSampleDist(fname)
1524        String fname
1525       
1526        return(getRealValueFromHeader(fname,288))
1527end
1528
1529//wavelength is at byte 292
1530Function getWavelength(fname)
1531        String fname
1532       
1533        return(getRealValueFromHeader(fname,292))
1534end
1535
1536//wavelength spread is at byte 296
1537Function getWavelengthSpread(fname)
1538        String fname
1539       
1540        return(getRealValueFromHeader(fname,296))
1541end
1542
1543//transmission detector count is at byte 388
1544Function getTransDetectorCounts(fname)
1545        String fname
1546       
1547        return(getRealValueFromHeader(fname,388))
1548end
1549
1550//detector pixel X size is at byte 220
1551Function getDetectorPixelXSize(fname)
1552        String fname
1553       
1554        return(getRealValueFromHeader(fname,220))
1555end
1556
1557//detector pixel Y size is at byte 232
1558Function getDetectorPixelYSize(fname)
1559        String fname
1560       
1561        return(getRealValueFromHeader(fname,232))
1562end
1563
1564// stub for ILL - power is written to their header, not ours
1565Function getReactorPower(fname)
1566        String fname
1567
1568        return 0
1569
1570end
1571
1572//////  integer values
1573
1574Function getIntegerFromHeader(fname,start)
1575        String fname                            //full path:name
1576        Variable start          //starting byte
1577       
1578        Variable refnum,val
1579        Open/R refNum as fname
1580        FSetPos refNum,start
1581        FBinRead/B=3/F=3 refnum,val
1582        Close refnum
1583       
1584        return(val)
1585End
1586
1587//total count time is at byte 31       
1588Function getCountTime(fname)
1589        String fname
1590        return(getIntegerFromHeader(fname,31))
1591end
1592
1593
1594//reads the wavelength from a reduced data file (not very reliable)
1595// - does not work with NSORTed files
1596// - only used in FIT/RPA (which itself is almost NEVER used...)
1597//
1598Function GetLambdaFromReducedData(tempName)
1599        String tempName
1600       
1601        String junkString
1602        Variable lambdaFromFile, fileVar
1603        lambdaFromFile = 6.0
1604        Open/R/P=catPathName fileVar as tempName
1605        FReadLine fileVar, junkString
1606        FReadLine fileVar, junkString
1607        FReadLine fileVar, junkString
1608        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
1609                FReadLine/N=11 fileVar, junkString
1610                FReadLine/N=10 fileVar, junkString
1611                lambdaFromFile = str2num(junkString)
1612        endif
1613        Close fileVar
1614       
1615        return(lambdaFromFile)
1616End
1617
1618/////   TRANSMISSION RELATED FUNCTIONS    ////////
1619//box coordinate are returned by reference
1620// filename is the full path:name
1621Function getXYBoxFromFile(filename,x1,x2,y1,y2)
1622        String filename
1623        Variable &x1,&x2,&y1,&y2
1624       
1625        Variable refnum
1626//      String tmpFile = FindValidFilename(filename)
1627               
1628//      Open/R/P=catPathName refnum as tmpFile
1629        Open/R refnum as filename
1630        FSetPos refnum,478
1631        FBinRead/F=3/B=3 refnum, x1
1632        FBinRead/F=3/B=3 refnum, x2
1633        FBinRead/F=3/B=3 refnum, y1
1634        FBinRead/F=3/B=3 refnum, y2
1635        Close refnum
1636       
1637        return(0)
1638End
1639
1640//go find the file, open it and write 4 integers to the file
1641//in the positions for analysis.rows(2), .cols(2) = 4 unused 4byte integers
1642Function WriteXYBoxToHeader(filename,x1,x2,y1,y2)
1643        String filename
1644        Variable x1,x2,y1,y2
1645       
1646        Variable refnum
1647        Open/A/T="????TEXT" refnum as filename
1648        FSetPos refnum,478
1649        FBinWrite/F=3/B=3 refNum, x1
1650        FBinWrite/F=3/B=3 refNum, x2
1651        FBinWrite/F=3/B=3 refNum, y1
1652        FBinWrite/F=3/B=3 refNum, y2
1653        //move to the end of the file before closing
1654        FStatus refnum
1655        FSetPos refnum,V_logEOF
1656        Close refnum
1657       
1658        return(0)
1659End
1660
1661//associated file suffix is the first 4 characters of a text field starting
1662// at byte 404
1663// suffix must be four characters long, if not, it's truncated
1664//
1665Function WriteAssocFileSuffixToHeader(fname,suffix)
1666        String fname,suffix
1667               
1668        suffix = suffix[0,3]            //limit to 4 characters
1669        WriteTextToHeader(fname,suffix,404)
1670       
1671        return(0)
1672end
1673
1674
1675// Jan 2008
1676// it has been determined that the true pixel dimension of the ordela detectors is not 5.0 mm
1677// but somewhat larger (5.08? mm). "new" data files will be written out with the proper size
1678// and old files will be patched batchwise to put the prpoer value in the header
1679
1680Proc PatchDetectorPixelSize(firstFile,lastFile,XSize,YSize)
1681        Variable firstFile=1,lastFile=100,XSize=5.08,YSize=5.08
1682
1683        fPatchDetectorPixelSize(firstFile,lastFile,XSize,YSize)
1684
1685End
1686
1687Proc ReadDetectorPixelSize(firstFile,lastFile)
1688        Variable firstFile=1,lastFile=100
1689       
1690        fReadDetectorPixelSize(firstFile,lastFile)
1691End
1692
1693// simple utility to patch the detector pixel size in the file headers
1694// pass in the dimensions in mm
1695// lo is the first file number
1696// hi is the last file number (inclusive)
1697//
1698Function fPatchDetectorPixelSize(lo,hi,xdim,ydim)
1699        Variable lo,hi,xdim,ydim
1700       
1701        Variable ii
1702        String file
1703       
1704        //loop over all files
1705        for(ii=lo;ii<=hi;ii+=1)
1706                file = FindFileFromRunNumber(ii)
1707                if(strlen(file) != 0)
1708                        WriteDetPixelXToHeader(file,xdim)
1709                        WriteDetPixelyToHeader(file,ydim)
1710                else
1711                        printf "run number %d not found\r",ii
1712                endif
1713        endfor
1714       
1715        return(0)
1716End
1717
1718// simple utility to read the pixel size stored in the file header
1719Function fReadDetectorPixelSize(lo,hi)
1720        Variable lo,hi
1721       
1722        String file
1723        Variable xdim,ydim,ii
1724       
1725        for(ii=lo;ii<=hi;ii+=1)
1726                file = FindFileFromRunNumber(ii)
1727                if(strlen(file) != 0)
1728                        xdim = getDetectorPixelXSize(file)
1729                        ydim = getDetectorPixelYSize(file)
1730                        printf "File %d:  Pixel dimensions (mm): X = %g\t Y = %g\r",ii,xdim,ydim
1731                else
1732                        printf "run number %d not found\r",ii
1733                endif
1734        endfor
1735       
1736        return(0)
1737End
1738
1739
1740
1741//*******************
1742//************
1743// simple command - line utilities to convert/unconvert the header value
1744// that flags files as using lenses
1745//
1746// stored in reals[28], header byte start @ 300
1747//
1748// currently, two values (0 | 1) = (no lens | yes lens)
1749// ideally, this field will have the actual number of lenses inserted.
1750//
1751// this is used in getResolution (reads the reals[]) and switches the calculation
1752//************
1753
1754Proc ConvertToLens(RunNumber)
1755        Variable RunNumber
1756        HeaderToLensResolution(RunNumber)
1757End
1758
1759Proc ConvertToPinhole(RunNumber)
1760        Variable RunNumber
1761        HeaderToPinholeResolution(RunNumber)
1762End
1763
1764// sets the flag to zero in the file (= 0)
1765Function HeaderToPinholeResolution(num)
1766        Variable num   
1767       
1768        //Print "UnConvert"
1769        String fullname=""
1770       
1771        fullname = FindFileFromRunNumber(num)
1772        Print fullname
1773        //report error or change the file
1774        if(cmpstr(fullname,"")==0)
1775                Print "HeaderToPinhole - file not found"
1776        else
1777                //Print "Unconvert",fullname
1778                WriteVAXReal(fullname,0,300)
1779        Endif
1780        return(0)
1781End
1782
1783// sets the flag to one in the file (= 1)
1784Function HeaderToLensResolution(num)
1785        Variable num   
1786       
1787        //Print "UnConvert"
1788        String fullname=""
1789       
1790        fullname = FindFileFromRunNumber(num)
1791        Print fullname
1792        //report error or change the file
1793        if(cmpstr(fullname,"")==0)
1794                Print "HeaderToPinhole - file not found"
1795        else
1796                //Print "Unconvert",fullname
1797                WriteVAXReal(fullname,1,300)
1798        Endif
1799        return(0)
1800End
1801
1802
1803// given a data folder, write out the corresponding VAX binary data file.
1804//
1805// I don't think that I can generate a STRUCT and then lay that down - since the
1806// VAX FP format has to be duplicated with a write/read/flip/re-write dance...
1807//
1808// seems to work correctly byte for byte
1809// compression has bee implmented also, for complete replication of the format (n>32767 in a cell)
1810//
1811// SRK 29JAN09
1812//
1813// other functions needed:
1814//
1815//
1816// one to generate a fake data file name, and put the matching name in the data header
1817// !! must fake the Annn suffix too! this is used...
1818// use a prefix, keep a run number, initials SIM, and alpha as before (start randomly, don't bother changing?)
1819//
1820// for right now, keep a run number, and generate
1821// PREFIXnnn.SA2_SIM_Annn
1822// also, start the index @ 100 to avoid leading zeros (although I have the functions available)
1823
1824// one to generate the date/time string in VAX format, right # characters// Print Secs2Time(DateTime,3)                         // Prints 13:07:29
1825// Print Secs2Time(DateTime,3)                          // Prints 13:07:29
1826//      Print Secs2Date(DateTime,-2)            // 1993-03-14                   //this call is independent of System date/time!//
1827//
1828// for now, 20 characters 01-JAN-2009 12:12:12
1829//
1830
1831// simulation should call as ("SAS","",0) to bypass the dialog, and to fill the header
1832// this could be modified in the future to be more generic
1833//
1834///
1835Function WriteVAXData(type,fullpath,dialog)
1836        String type,fullpath
1837        Variable dialog         //=1 will present dialog for name
1838       
1839        String destStr=""
1840        Variable refNum,ii,val,err
1841       
1842       
1843        destStr = "root:Packages:NIST:"+type
1844       
1845        SetDataFolder $destStr
1846        WAVE intw=integersRead
1847        WAVE rw=realsRead
1848        WAVE/T textw=textRead
1849        WAVE data=linear_data
1850       
1851        //check each wave
1852        If(!(WaveExists(intw)))
1853                Abort "intw DNExist WriteVAXData()"
1854        Endif
1855        If(!(WaveExists(rw)))
1856                Abort "rw DNExist WriteVAXData()"
1857        Endif
1858        If(!(WaveExists(textw)))
1859                Abort "textw DNExist WriteVAXData()"
1860        Endif
1861        If(!(WaveExists(data)))
1862                Abort "linear_data DNExist WriteVAXData()"
1863        Endif
1864       
1865       
1866//      if(dialog)
1867//              PathInfo/S catPathName
1868//              fullPath = DoSaveFileDialog("Save data as")
1869//              If(cmpstr(fullPath,"")==0)
1870//                      //user cancel, don't write out a file
1871//                      Close/A
1872//                      Abort "no data file was written"
1873//              Endif
1874//              //Print "dialog fullpath = ",fullpath
1875//      Endif
1876       
1877        // save to home, or get out
1878        //
1879        PathInfo home
1880        if(V_flag       == 0)
1881                Abort "no save path defined. Save the experiment to generate a home path"
1882        endif
1883       
1884        fullPath = S_path               //not the full path yet, still need the name, after the header is filled
1885       
1886       
1887        Make/O/B/U/N=33316 tmpFile              //unsigned integers for a blank data file
1888        tmpFile=0
1889       
1890        Make/O/W/N=16401 dataWRecMarkers
1891        AddRecordMarkers(data,dataWRecMarkers)
1892       
1893        // need to re-compress?? maybe never a problem, but should be done for the odd case
1894        dataWRecMarkers = CompressI4toI2(dataWRecMarkers)               //unless a pixel value is > 32767, the same values are returned
1895       
1896        // fill the last bits of the header information
1897        err = SimulationVAXHeader(type)
1898        if (err == -1)
1899                Abort "no sample label entered - no file written"                       // User did not fill in header correctly/completely
1900        endif
1901        fullPath = fullPath + textW[0]
1902       
1903        // lay down a blank file
1904        Open refNum as fullpath
1905                FBinWrite refNum,tmpFile                        //file is the right size, but all zeroes
1906        Close refNum
1907       
1908        // fill up the header
1909        // text values
1910        // elements of textW are already the correct length set by the read, but just make sure
1911        String str
1912       
1913        if(strlen(textw[0])>21)
1914                textw[0] = (textw[0])[0,20]
1915        endif
1916        if(strlen(textw[1])>20)
1917                textw[1] = (textw[1])[0,19]
1918        endif
1919        if(strlen(textw[2])>3)
1920                textw[2] = (textw[2])[0,2]
1921        endif
1922        if(strlen(textw[3])>11)
1923                textw[3] = (textw[3])[0,10]
1924        endif
1925        if(strlen(textw[4])>1)
1926                textw[4] = (textw[4])[0]
1927        endif
1928        if(strlen(textw[5])>8)
1929                textw[5] = (textw[5])[0,7]
1930        endif
1931        if(strlen(textw[6])>60)
1932                textw[6] = (textw[6])[0,59]
1933        endif
1934        if(strlen(textw[7])>6)
1935                textw[7] = (textw[7])[0,5]
1936        endif
1937        if(strlen(textw[8])>6)
1938                textw[8] = (textw[8])[0,5]
1939        endif
1940        if(strlen(textw[9])>6)
1941                textw[9] = (textw[9])[0,5]
1942        endif
1943        if(strlen(textw[10])>42)
1944                textw[10] = (textw[10])[0,41]
1945        endif   
1946       
1947        ii=0
1948        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
1949                str = textW[ii]
1950                FSetPos refnum,2                                                        ////file name
1951                FBinWrite/F=0 refnum, str      //native object format (character)
1952                ii+=1
1953                str = textW[ii]
1954                FSetPos refnum,55                                                       ////date/time
1955                FBinWrite/F=0 refnum, str
1956                ii+=1
1957                str = textW[ii]
1958                FSetPos refnum,75                                                       ////type
1959                FBinWrite/F=0 refnum, str
1960                ii+=1
1961                str = textW[ii]
1962                FSetPos refnum,78                                               ////def dir
1963                FBinWrite/F=0 refnum, str
1964                ii+=1
1965                str = textW[ii]
1966                FSetPos refnum,89                                               ////mode
1967                FBinWrite/F=0 refnum, str
1968                ii+=1
1969                str = textW[ii]
1970                FSetPos refnum,90                                               ////reserve
1971                FBinWrite/F=0 refnum, str
1972                ii+=1
1973                str = textW[ii]
1974                FSetPos refnum,98                                               ////@98, sample label
1975                FBinWrite/F=0 refnum, str
1976                ii+=1
1977                str = textW[ii]
1978                FSetPos refnum,202                                              //// T units
1979                FBinWrite/F=0 refnum, str
1980                ii+=1
1981                str = textW[ii]
1982                FSetPos refnum,208                                              //// F units
1983                FBinWrite/F=0 refnum, str
1984                ii+=1
1985                str = textW[ii]
1986                FSetPos refnum,214                                              ////det type
1987                FBinWrite/F=0 refnum, str
1988                ii+=1
1989                str = textW[ii]
1990                FSetPos refnum,404                                              ////reserve
1991                FBinWrite/F=0 refnum, str
1992       
1993                //move to the end of the file before closing
1994                FStatus refnum
1995                FSetPos refnum,V_logEOF
1996        Close refnum
1997       
1998       
1999        // integer values (4 bytes)
2000        ii=0
2001        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
2002                val = intw[ii]
2003                FSetPos refnum,23                                                       //nprefactors
2004                FBinWrite/B=3/F=3 refnum, val      //write a 4-byte integer
2005                ii+=1
2006                val=intw[ii]
2007                FSetPos refnum,27                                                       //ctime
2008                FBinWrite/B=3/F=3 refnum, val
2009                ii+=1
2010                val=intw[ii]
2011                FSetPos refnum,31                                                       //rtime
2012                FBinWrite/B=3/F=3 refnum, val
2013                ii+=1
2014                val=intw[ii]
2015                FSetPos refnum,35                                                       //numruns
2016                FBinWrite/B=3/F=3 refnum, val
2017                ii+=1
2018                val=intw[ii]
2019                FSetPos refnum,174                                                      //table
2020                FBinWrite/B=3/F=3 refnum, val
2021                ii+=1
2022                val=intw[ii]
2023                FSetPos refnum,178                                                      //holder
2024                FBinWrite/B=3/F=3 refnum, val
2025                ii+=1
2026                val=intw[ii]
2027                FSetPos refnum,182                                                      //blank
2028                FBinWrite/B=3/F=3 refnum, val
2029                ii+=1
2030                val=intw[ii]
2031                FSetPos refnum,194                                                      //tctrlr
2032                FBinWrite/B=3/F=3 refnum, val
2033                ii+=1
2034                val=intw[ii]
2035                FSetPos refnum,198                                                      //magnet
2036                FBinWrite/B=3/F=3 refnum, val
2037                ii+=1
2038                val=intw[ii]
2039                FSetPos refnum,244                                                      //det num
2040                FBinWrite/B=3/F=3 refnum, val
2041                ii+=1
2042                val=intw[ii]
2043                FSetPos refnum,248                                                      //det spacer
2044                FBinWrite/B=3/F=3 refnum, val
2045                ii+=1
2046                val=intw[ii]
2047                FSetPos refnum,308                                                      //tslice mult
2048                FBinWrite/B=3/F=3 refnum, val
2049                ii+=1
2050                val=intw[ii]
2051                FSetPos refnum,312                                                      //tsclice ltslice
2052                FBinWrite/B=3/F=3 refnum, val
2053                ii+=1
2054                val=intw[ii]
2055                FSetPos refnum,332                                                      //extra
2056                FBinWrite/B=3/F=3 refnum, val
2057                ii+=1
2058                val=intw[ii]
2059                FSetPos refnum,336                                                      //reserve
2060                FBinWrite/B=3/F=3 refnum, val
2061                ii+=1
2062                val=intw[ii]
2063                FSetPos refnum,376                                                      //blank1
2064                FBinWrite/B=3/F=3 refnum, val
2065                ii+=1
2066                val=intw[ii]
2067                FSetPos refnum,380                                                      //blank2
2068                FBinWrite/B=3/F=3 refnum, val
2069                ii+=1
2070                val=intw[ii]
2071                FSetPos refnum,384                                                      //blank3
2072                FBinWrite/B=3/F=3 refnum, val
2073                ii+=1
2074                val=intw[ii]
2075                FSetPos refnum,458                                                      //spacer
2076                FBinWrite/B=3/F=3 refnum, val
2077                ii+=1
2078                val=intw[ii]
2079                FSetPos refnum,478                                                      //box x1
2080                FBinWrite/B=3/F=3 refnum, val
2081                ii+=1
2082                val=intw[ii]
2083                FSetPos refnum,482                                                      //box x2
2084                FBinWrite/B=3/F=3 refnum, val
2085                ii+=1
2086                val=intw[ii]
2087                FSetPos refnum,486                                                      //box y1
2088                FBinWrite/B=3/F=3 refnum, val
2089                ii+=1
2090                val=intw[ii]
2091                FSetPos refnum,490                                                      //box y2
2092                FBinWrite/B=3/F=3 refnum, val
2093               
2094                //move to the end of the file before closing
2095                FStatus refnum
2096                FSetPos refnum,V_logEOF
2097        Close refnum
2098       
2099               
2100        //VAX 4-byte FP values. No choice here but to write/read/re-write to get
2101        // the proper format. there are 52! values to write
2102        //WriteVAXReal(fullpath,rw[n],start)
2103        // [0]
2104        WriteVAXReal(fullpath,rw[0],39)
2105        WriteVAXReal(fullpath,rw[1],43)
2106        WriteVAXReal(fullpath,rw[2],47)
2107        WriteVAXReal(fullpath,rw[3],51)
2108        WriteVAXReal(fullpath,rw[4],158)
2109        WriteVAXReal(fullpath,rw[5],162)
2110        WriteVAXReal(fullpath,rw[6],166)
2111        WriteVAXReal(fullpath,rw[7],170)
2112        WriteVAXReal(fullpath,rw[8],186)
2113        WriteVAXReal(fullpath,rw[9],190)
2114        // [10]
2115        WriteVAXReal(fullpath,rw[10],220)
2116        WriteVAXReal(fullpath,rw[11],224)
2117        WriteVAXReal(fullpath,rw[12],228)
2118        WriteVAXReal(fullpath,rw[13],232)
2119        WriteVAXReal(fullpath,rw[14],236)
2120        WriteVAXReal(fullpath,rw[15],240)
2121        WriteVAXReal(fullpath,rw[16],252)
2122        WriteVAXReal(fullpath,rw[17],256)
2123        WriteVAXReal(fullpath,rw[18],260)
2124        WriteVAXReal(fullpath,rw[19],264)
2125        // [20]
2126        WriteVAXReal(fullpath,rw[20],268)
2127        WriteVAXReal(fullpath,rw[21],272)
2128        WriteVAXReal(fullpath,rw[22],276)
2129        WriteVAXReal(fullpath,rw[23],280)
2130        WriteVAXReal(fullpath,rw[24],284)
2131        WriteVAXReal(fullpath,rw[25],288)
2132        WriteVAXReal(fullpath,rw[26],292)
2133        WriteVAXReal(fullpath,rw[27],296)
2134        WriteVAXReal(fullpath,rw[28],300)
2135        WriteVAXReal(fullpath,rw[29],320)
2136        // [30]
2137        WriteVAXReal(fullpath,rw[30],324)
2138        WriteVAXReal(fullpath,rw[31],328)
2139        WriteVAXReal(fullpath,rw[32],348)
2140        WriteVAXReal(fullpath,rw[33],352)
2141        WriteVAXReal(fullpath,rw[34],356)
2142        WriteVAXReal(fullpath,rw[35],360)
2143        WriteVAXReal(fullpath,rw[36],364)
2144        WriteVAXReal(fullpath,rw[37],368)
2145        WriteVAXReal(fullpath,rw[38],372)
2146        WriteVAXReal(fullpath,rw[39],388)
2147        // [40]
2148        WriteVAXReal(fullpath,rw[40],392)
2149        WriteVAXReal(fullpath,rw[41],396)
2150        WriteVAXReal(fullpath,rw[42],400)
2151        WriteVAXReal(fullpath,rw[43],450)
2152        WriteVAXReal(fullpath,rw[44],454)
2153        WriteVAXReal(fullpath,rw[45],470)
2154        WriteVAXReal(fullpath,rw[46],474)
2155        WriteVAXReal(fullpath,rw[47],494)
2156        WriteVAXReal(fullpath,rw[48],498)
2157        WriteVAXReal(fullpath,rw[49],502)
2158        // [50]
2159        WriteVAXReal(fullpath,rw[50],506)
2160        WriteVAXReal(fullpath,rw[51],510)
2161       
2162       
2163        // write out the data
2164        Open refNum as fullpath
2165                FSetPos refnum,514                                      //  OK
2166                FBinWrite/F=2/B=3 refNum,dataWRecMarkers                //don't trust the native format
2167                FStatus refNum
2168                FSetPos refNum,V_logEOF
2169        Close refNum
2170       
2171        // all done
2172        Killwaves/Z tmpFile,dataWRecMarkers
2173       
2174        Print "Saved VAX binary data as:  ",textW[0]
2175        SetDatafolder root:
2176        return(0)
2177End
2178
2179
2180Function AddRecordMarkers(in,out)
2181        Wave in,out
2182       
2183        Variable skip,ii
2184
2185//      Duplicate/O in,out
2186//      Redimension/N=16401 out
2187
2188        out=0
2189       
2190        ii=0
2191        skip=0
2192        out[ii] = 1
2193        ii+=1
2194        do
2195                if(mod(ii+skip,1022)==0)
2196                        out[ii+skip] = 0                //999999
2197                        skip+=1                 //increment AFTER filling the current marker
2198                endif
2199                out[ii+skip] = in[ii-1]
2200                ii+=1
2201        while(ii<=16384)
2202       
2203       
2204        return(0)
2205End
2206
2207
2208
2209
2210//        INTEGER*2 FUNCTION I4ToI2(I4)
2211//C
2212//C       Original author : Jim Rhyne
2213//C       Modified by     : Frank Chen 09/26/90
2214//C
2215//C       I4ToI2 = I4,                            I4 in [0,32767]
2216//C       I4ToI2 = -777,                          I4 in (2767000,...)
2217//C       I4ToI2 mapped to -13277 to -32768,      otherwise
2218//C
2219//C       the mapped values [-776,-1] and [-13276,-778] are not used
2220//C
2221//C       I4max should be 2768499, this value will maps to -32768
2222//C       and mantissa should be compared  using
2223//C               IF (R4 .GE. IPW)
2224//C       instead of
2225//C               IF (R4 .GT. (IPW - 1.0))
2226//C
2227//
2228//
2229//C       I4      :       input I*4
2230//C       R4      :       temperory real number storage
2231//C       IPW     :       IPW = IB ** ND
2232//C       NPW     :       number of power
2233//C       IB      :       Base value
2234//C       ND      :       Number of precision digits
2235//C       I4max   :       max data value w/ some error
2236//C       I2max   :       max data value w/o error
2237//C       Error   :       when data value > I4max
2238//C
2239//        INTEGER*4       I4
2240//        INTEGER*4       NPW
2241//        REAL*4          R4
2242//        INTEGER*4       IPW
2243//        INTEGER*4       IB      /10/
2244//        INTEGER*4       ND      /4/
2245//        INTEGER*4       I4max   /2767000/
2246//        INTEGER*4       I2max   /32767/
2247//        INTEGER*4       Error   /-777/
2248//
2249Function CompressI4toI2(i4)
2250        Variable i4
2251
2252        Variable npw,ipw,ib,nd,i4max,i2max,error,i4toi2
2253        Variable r4
2254       
2255        ib=10
2256        nd=4
2257        i4max=2767000
2258        i2max=32767
2259        error=-777
2260       
2261        if(i4 <= i4max)
2262                r4=i4
2263                if(r4 > i2max)
2264                        ipw = ib^nd
2265                        npw=0
2266                        do
2267                                if( !(r4 > (ipw-1)) )           //to simulate a do-while loop evaluating at top
2268                                        break
2269                                endif
2270                                npw=npw+1
2271                                r4=r4/ib               
2272                        while (1)
2273                        i4toi2 = -1*trunc(r4+ipw*npw)
2274                else
2275                        i4toi2 = trunc(r4)              //shouldn't I just return i4 (as a 2 byte value?)
2276                endif
2277        else
2278                i4toi2=error
2279        endif
2280        return(i4toi2)
2281End
2282
2283
2284// function to fill the extra bits of header information to make a "complete"
2285// simulated VAX data file.
2286//
2287//
2288Function SimulationVAXHeader(folder)
2289        String folder
2290
2291        Wave rw=root:Packages:NIST:SAS:realsRead
2292        Wave iw=root:Packages:NIST:SAS:integersRead
2293        Wave/T tw=root:Packages:NIST:SAS:textRead
2294        Wave res=root:Packages:NIST:SAS:results
2295       
2296// integers needed:
2297        //[2] count time
2298        NVAR ctTime = root:Packages:NIST:SAS:gCntTime
2299        iw[2] = ctTime
2300       
2301//reals are partially set in SASCALC initializtion
2302        //remaining values are updated automatically as SASCALC is modified
2303        // -- but still need:
2304        //      [0] monitor count
2305        //      [2] detector count (w/o beamstop)
2306        //      [4] transmission
2307        //      [5] thickness (in cm)
2308        NVAR imon = root:Packages:NIST:SAS:gImon
2309        rw[0] = imon
2310        rw[2] = res[9]
2311        rw[4] = res[8]
2312        NVAR thick = root:Packages:NIST:SAS:gThick
2313        rw[5] = thick
2314       
2315// text values needed:
2316// be sure they are padded to the correct length
2317        // [0] filename (do I fake a VAX name? probably yes...)
2318        // [1] date/time in VAX format
2319        // [2] type (use SIM)
2320        // [3] def dir (use [NG7SANS99])
2321        // [4] mode? C
2322        // [5] reserve (another date), prob not needed
2323        // [6] sample label
2324        // [9] det type "ORNL  " (6 chars)
2325       
2326        tw[1] = "01-JAN-2009 12:12:12"
2327        tw[2] = "SIM"
2328        tw[3] = "[NG7SANS99]"
2329        tw[4] = "C"
2330        tw[5] = "01JAN09 "
2331        tw[9] = "ORNL  "
2332       
2333        NVAR index = root:Packages:NIST:SAS:gSaveIndex
2334        SVAR prefix = root:Packages:NIST:SAS:gSavePrefix
2335
2336        tw[0] = prefix+num2str(index)+".SA2_SIM_A"+num2str(index)
2337        index += 1
2338       
2339        String labelStr=" "     
2340        Prompt labelStr, "Enter sample label "          // Set prompt for x param
2341        DoPrompt "Enter sample label", labelStr
2342        if (V_Flag)
2343                //Print "no sample label entered - no file written"
2344                index -=1
2345                return -1                                                               // User canceled
2346        endif
2347       
2348        labelStr = PadString(labelStr,60,0x20)  //60 fortran-style spaces
2349        tw[6] = labelStr[0,59]
2350       
2351        return(0)
2352End
2353
2354Function ExamineHeader(type)
2355        String type
2356
2357        String data_folder = type
2358        String dataPath = "root:Packages:NIST:"+data_folder
2359        String cur_folder = "ExamineHeader"
2360        String curPath = "root:Packages:NIST:"+cur_folder
2361       
2362        //SetDataFolder curPath
2363
2364        Wave intw=$(dataPath+":IntegersRead")
2365        Wave realw=$(dataPath+":RealsRead")
2366        Wave/T textw=$(dataPath+":TextRead")
2367        Wave logw=$(dataPath+":LogicalsRead")
2368
2369
2370        print "----------------------------------"
2371        print "Header Details"
2372        print "----------------------------------"
2373        print "fname :\t\t"+textw[0]
2374        //
2375        print "run.npre :\t\t"+num2str(intw[0])
2376        print "run.ctime :\t\t"+num2str(intw[1])
2377        print "run.rtime :\t\t"+num2str(intw[2])
2378        print "run.numruns :\t\t"+num2str(intw[3])
2379        //
2380        print "run.moncnt :\t\t"+num2str(realw[0])
2381        print "run.savmon :\t\t"+num2str(realw[1])
2382        print "run.detcnt :\t\t"+num2str(realw[2])
2383        print "run.atten :\t\t"+num2str(realw[3])       
2384        //
2385        print "run.timdat:\t\t"+textw[1]
2386        print "run.type:\t\t"+textw[2]
2387        print "run.defdir:\t\t"+textw[3]
2388        print "run.mode:\t\t"+textw[4]
2389        print "run.reserve:\t\t"+textw[5]
2390        print "sample.labl:\t\t"+textw[6]
2391        //
2392        print "sample.trns:\t\t"+num2str(realw[4])
2393        print "sample.thk:\t\t"+num2str(realw[5])
2394        print "sample.position:\t\t"+num2str(realw[6])
2395        print "sample.rotang:\t\t"+num2str(realw[7])
2396        //
2397        print "sample.table:\t\t"+num2str(intw[4])
2398        print "sample.holder:\t\t"+num2str(intw[5])
2399        print "sample.blank:\t\t"+num2str(intw[6])
2400        //
2401        print "sample.temp:\t\t"+num2str(realw[8])
2402        print "sample.field:\t\t"+num2str(realw[9])     
2403        //
2404        print "sample.tctrlr:\t\t"+num2str(intw[7])
2405        print "sample.magnet:\t\t"+num2str(intw[8])
2406        //
2407        print "sample.tunits:\t\t"+textw[7]
2408        print "sample.funits:\t\t"+textw[8]
2409        print "det.typ:\t\t"+textw[9]
2410        //
2411        print "det.calx(1):\t\t"+num2str(realw[10])
2412        print "det.calx(2):\t\t"+num2str(realw[11])
2413        print "det.calx(3):\t\t"+num2str(realw[12])
2414        print "det.caly(1):\t\t"+num2str(realw[13])
2415        print "det.caly(2):\t\t"+num2str(realw[14])
2416        print "det.caly(3):\t\t"+num2str(realw[15])
2417        //
2418        print "det.num:\t\t"+num2str(intw[9])
2419        print "det.spacer:\t\t"+num2str(intw[10])
2420        //
2421        print "det.beamx:\t\t"+num2str(realw[16])
2422        print "det.beamy:\t\t"+num2str(realw[17])
2423        print "det.dis:\t\t"+num2str(realw[18])
2424        print "det.offset:\t\t"+num2str(realw[19])
2425        print "det.siz:\t\t"+num2str(realw[20])
2426        print "det.bstop:\t\t"+num2str(realw[21])
2427        print "det.blank:\t\t"+num2str(realw[22])
2428        print "resolution.ap1:\t\t"+num2str(realw[23])
2429        print "resolution.ap2:\t\t"+num2str(realw[24])
2430        print "resolution.ap12dis:\t\t"+num2str(realw[25])
2431        print "resolution.lmda:\t\t"+num2str(realw[26])
2432        print "resolution.dlmda:\t\t"+num2str(realw[27])
2433        print "resolution.nlenses:\t\t"+num2str(realw[28])     
2434        //
2435        print "tslice.slicing:\t\t"+num2str(logw[0])
2436        //
2437        print "tslice.multfact:\t\t"+num2str(intw[11])
2438        print "tslice.ltslice:\t\t"+num2str(intw[12])
2439        //
2440        print "temp.printemp:\t\t"+num2str(logw[1])
2441        //
2442        print "temp.hold:\t\t"+num2str(realw[29])
2443        print "temp.err:\t\t"+num2str(realw[30])
2444        print "temp.blank:\t\t"+num2str(realw[31])
2445        //
2446        print "temp.extra:\t\t"+num2str(intw[13])
2447        print "temp.err:\t\t"+num2str(intw[14])
2448        //
2449        print "magnet.printmag:\t\t"+num2str(logw[2])
2450        print "magnet.sensor:\t\t"+num2str(logw[3])
2451        //
2452        print "magnet.current:\t\t"+num2str(realw[32])
2453        print "magnet.conv:\t\t"+num2str(realw[33])
2454        print "magnet.fieldlast:\t\t"+num2str(realw[34])
2455        print "magnet.blank:\t\t"+num2str(realw[35])
2456        print "magnet.spacer:\t\t"+num2str(realw[36])
2457        print "bmstp.xpos:\t\t"+num2str(realw[37])
2458        print "bmstop.ypos:\t\t"+num2str(realw[38])
2459        //     
2460        print "params.blank1:\t\t"+num2str(intw[15])
2461        print "params.blank2:\t\t"+num2str(intw[16])
2462        print "params.blank3:\t\t"+num2str(intw[17])
2463        //
2464        print "params.trnscnt:\t\t"+num2str(realw[39])
2465        print "params.extra1:\t\t"+num2str(realw[40])
2466        print "params.extra2:\t\t"+num2str(realw[41])
2467        print "params.extra3:\t\t"+num2str(realw[42])
2468        //     
2469        print "params.reserve:\t\t"+textw[10]
2470        //
2471        print "voltage.printemp:\t\t"+num2str(logw[4])
2472        //
2473        print "voltage.volts:\t\t"+num2str(realw[43])
2474        print "voltage.blank:\t\t"+num2str(realw[44])
2475        //     
2476        print "voltage.spacer:\t\t"+num2str(intw[18])
2477        //
2478        print "polarization.printpol:\t\t"+num2str(logw[5])
2479        print "polarization.flipper:\t\t"+num2str(logw[6])
2480        //     
2481        print "polarization.horiz:\t\t"+num2str(realw[45])
2482        print "polarization.vert:\t\t"+num2str(realw[46])
2483        //
2484        print "analysis.rows(1):\t\t"+num2str(intw[19])
2485        print "analysis.rows(2):\t\t"+num2str(intw[20])
2486        print "analysis.cols(1):\t\t"+num2str(intw[21])
2487        print "analysis.cols(2):\t\t"+num2str(intw[22])
2488        //
2489        print "analysis.factor:\t\t"+num2str(realw[47])
2490        print "analysis.qmin:\t\t"+num2str(realw[48])
2491        print "analysis.qmax:\t\t"+num2str(realw[49])
2492        print "analysis.imin:\t\t"+num2str(realw[50])
2493        print "analysis.imax:\t\t"+num2str(realw[51])
2494
2495End
Note: See TracBrowser for help on using the repository browser.