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

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

Added a calculation of the total fraction of multiple coherent scattering. This value is now displayed on the 1D sim panel and on the UCALC panel. If the total fraction of multiple coherent scattering (relative to the fraction coherently scattered) is greater than 0.10, then the field turns red as a warning.

Changed the numbering and suffix scheme for saving simulated VAX raw data files.

File size: 74.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
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/D/N=23 $"root:Packages:NIST:RAW:IntegersRead"
88        Make/O/D/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/D/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/D/N=23 $(curPath + ":IntegersRead")
512        Make/O/D/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/D/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/D/N=23 $("root:Packages:NIST:"+destFolder+":IntegersRead")
921        Make/O/D/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////// OCT 2009, facility specific bits from MonteCarlo functions()
1864//"type" is the data folder that has the data array that is to be (re)written as a full
1865// data file, as if it was a raw data file
1866//
1867Function/S Write_RawData_File(type,fullpath,dialog)
1868        String type,fullpath
1869        Variable dialog         //=1 will present dialog for name
1870       
1871        String filename = ""
1872        filename = Write_VAXRaw_Data(type,fullpath,dialog)
1873       
1874        return(filename)
1875End
1876
1877// given a data folder, write out the corresponding VAX binary data file.
1878//
1879// I don't think that I can generate a STRUCT and then lay that down - since the
1880// VAX FP format has to be duplicated with a write/read/flip/re-write dance...
1881//
1882// seems to work correctly byte for byte
1883// compression has bee implmented also, for complete replication of the format (n>32767 in a cell)
1884//
1885// SRK 29JAN09
1886//
1887// other functions needed:
1888//
1889//
1890// one to generate a fake data file name, and put the matching name in the data header
1891// !! must fake the Annn suffix too! this is used...
1892// use a prefix, keep a run number, initials SIM, and alpha as before (start randomly, don't bother changing?)
1893//
1894// for right now, keep a run number, and generate
1895// PREFIXnnn.SA2_SIM_Annn
1896// also, start the index @ 100 to avoid leading zeros (although I have the functions available)
1897
1898// one to generate the date/time string in VAX format, right # characters// Print Secs2Time(DateTime,3)                         // Prints 13:07:29
1899// Print Secs2Time(DateTime,3)                          // Prints 13:07:29
1900//      Print Secs2Date(DateTime,-2)            // 1993-03-14                   //this call is independent of System date/time!//
1901//
1902//
1903// simulation should call as ("SAS","",0) to bypass the dialog, and to fill the header
1904// this could be modified in the future to be more generic
1905//
1906///
1907// changed to return the string w/ the filename as written for later use
1908Function/S Write_VAXRaw_Data(type,fullpath,dialog)
1909        String type,fullpath
1910        Variable dialog         //=1 will present dialog for name
1911       
1912        String destStr=""
1913        Variable refNum,ii,val,err
1914       
1915       
1916        destStr = "root:Packages:NIST:"+type
1917       
1918        SetDataFolder $destStr
1919        WAVE intw=integersRead
1920        WAVE rw=realsRead
1921        WAVE/T textw=textRead
1922        WAVE data=linear_data
1923       
1924        //check each wave
1925        If(!(WaveExists(intw)))
1926                Abort "intw DNExist WriteVAXData()"
1927        Endif
1928        If(!(WaveExists(rw)))
1929                Abort "rw DNExist WriteVAXData()"
1930        Endif
1931        If(!(WaveExists(textw)))
1932                Abort "textw DNExist WriteVAXData()"
1933        Endif
1934        If(!(WaveExists(data)))
1935                Abort "linear_data DNExist WriteVAXData()"
1936        Endif
1937       
1938       
1939//      if(dialog)
1940//              PathInfo/S catPathName
1941//              fullPath = DoSaveFileDialog("Save data as")
1942//              If(cmpstr(fullPath,"")==0)
1943//                      //user cancel, don't write out a file
1944//                      Close/A
1945//                      Abort "no data file was written"
1946//              Endif
1947//              //Print "dialog fullpath = ",fullpath
1948//      Endif
1949       
1950        // save to home, or get out
1951        //
1952        PathInfo home
1953        if(V_flag       == 0)
1954                Abort "no save path defined. Save the experiment to generate a home path"
1955        endif
1956       
1957        fullPath = S_path               //not the full path yet, still need the name, after the header is filled
1958       
1959       
1960        Make/O/B/U/N=33316 tmpFile              //unsigned integers for a blank data file
1961        tmpFile=0
1962       
1963        Make/O/W/N=16401 dataWRecMarkers
1964        AddRecordMarkers(data,dataWRecMarkers)
1965       
1966        // need to re-compress?? maybe never a problem, but should be done for the odd case
1967        dataWRecMarkers = CompressI4toI2(dataWRecMarkers)               //unless a pixel value is > 32767, the same values are returned
1968       
1969        // fill the last bits of the header information
1970        err = SimulationVAXHeader(type)
1971        if (err == -1)
1972                Abort "no sample label entered - no file written"                       // User did not fill in header correctly/completely
1973        endif
1974        fullPath = fullPath + textW[0]
1975       
1976        // lay down a blank file
1977        Open refNum as fullpath
1978                FBinWrite refNum,tmpFile                        //file is the right size, but all zeroes
1979        Close refNum
1980       
1981        // fill up the header
1982        // text values
1983        // elements of textW are already the correct length set by the read, but just make sure
1984        String str
1985       
1986        if(strlen(textw[0])>21)
1987                textw[0] = (textw[0])[0,20]
1988        endif
1989        if(strlen(textw[1])>20)
1990                textw[1] = (textw[1])[0,19]
1991        endif
1992        if(strlen(textw[2])>3)
1993                textw[2] = (textw[2])[0,2]
1994        endif
1995        if(strlen(textw[3])>11)
1996                textw[3] = (textw[3])[0,10]
1997        endif
1998        if(strlen(textw[4])>1)
1999                textw[4] = (textw[4])[0]
2000        endif
2001        if(strlen(textw[5])>8)
2002                textw[5] = (textw[5])[0,7]
2003        endif
2004        if(strlen(textw[6])>60)
2005                textw[6] = (textw[6])[0,59]
2006        endif
2007        if(strlen(textw[7])>6)
2008                textw[7] = (textw[7])[0,5]
2009        endif
2010        if(strlen(textw[8])>6)
2011                textw[8] = (textw[8])[0,5]
2012        endif
2013        if(strlen(textw[9])>6)
2014                textw[9] = (textw[9])[0,5]
2015        endif
2016        if(strlen(textw[10])>42)
2017                textw[10] = (textw[10])[0,41]
2018        endif   
2019       
2020        ii=0
2021        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
2022                str = textW[ii]
2023                FSetPos refnum,2                                                        ////file name
2024                FBinWrite/F=0 refnum, str      //native object format (character)
2025                ii+=1
2026                str = textW[ii]
2027                FSetPos refnum,55                                                       ////date/time
2028                FBinWrite/F=0 refnum, str
2029                ii+=1
2030                str = textW[ii]
2031                FSetPos refnum,75                                                       ////type
2032                FBinWrite/F=0 refnum, str
2033                ii+=1
2034                str = textW[ii]
2035                FSetPos refnum,78                                               ////def dir
2036                FBinWrite/F=0 refnum, str
2037                ii+=1
2038                str = textW[ii]
2039                FSetPos refnum,89                                               ////mode
2040                FBinWrite/F=0 refnum, str
2041                ii+=1
2042                str = textW[ii]
2043                FSetPos refnum,90                                               ////reserve
2044                FBinWrite/F=0 refnum, str
2045                ii+=1
2046                str = textW[ii]
2047                FSetPos refnum,98                                               ////@98, sample label
2048                FBinWrite/F=0 refnum, str
2049                ii+=1
2050                str = textW[ii]
2051                FSetPos refnum,202                                              //// T units
2052                FBinWrite/F=0 refnum, str
2053                ii+=1
2054                str = textW[ii]
2055                FSetPos refnum,208                                              //// F units
2056                FBinWrite/F=0 refnum, str
2057                ii+=1
2058                str = textW[ii]
2059                FSetPos refnum,214                                              ////det type
2060                FBinWrite/F=0 refnum, str
2061                ii+=1
2062                str = textW[ii]
2063                FSetPos refnum,404                                              ////reserve
2064                FBinWrite/F=0 refnum, str
2065       
2066                //move to the end of the file before closing
2067                FStatus refnum
2068                FSetPos refnum,V_logEOF
2069        Close refnum
2070       
2071       
2072        // integer values (4 bytes)
2073        ii=0
2074        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
2075                val = intw[ii]
2076                FSetPos refnum,23                                                       //nprefactors
2077                FBinWrite/B=3/F=3 refnum, val      //write a 4-byte integer
2078                ii+=1
2079                val=intw[ii]
2080                FSetPos refnum,27                                                       //ctime
2081                FBinWrite/B=3/F=3 refnum, val
2082                ii+=1
2083                val=intw[ii]
2084                FSetPos refnum,31                                                       //rtime
2085                FBinWrite/B=3/F=3 refnum, val
2086                ii+=1
2087                val=intw[ii]
2088                FSetPos refnum,35                                                       //numruns
2089                FBinWrite/B=3/F=3 refnum, val
2090                ii+=1
2091                val=intw[ii]
2092                FSetPos refnum,174                                                      //table
2093                FBinWrite/B=3/F=3 refnum, val
2094                ii+=1
2095                val=intw[ii]
2096                FSetPos refnum,178                                                      //holder
2097                FBinWrite/B=3/F=3 refnum, val
2098                ii+=1
2099                val=intw[ii]
2100                FSetPos refnum,182                                                      //blank
2101                FBinWrite/B=3/F=3 refnum, val
2102                ii+=1
2103                val=intw[ii]
2104                FSetPos refnum,194                                                      //tctrlr
2105                FBinWrite/B=3/F=3 refnum, val
2106                ii+=1
2107                val=intw[ii]
2108                FSetPos refnum,198                                                      //magnet
2109                FBinWrite/B=3/F=3 refnum, val
2110                ii+=1
2111                val=intw[ii]
2112                FSetPos refnum,244                                                      //det num
2113                FBinWrite/B=3/F=3 refnum, val
2114                ii+=1
2115                val=intw[ii]
2116                FSetPos refnum,248                                                      //det spacer
2117                FBinWrite/B=3/F=3 refnum, val
2118                ii+=1
2119                val=intw[ii]
2120                FSetPos refnum,308                                                      //tslice mult
2121                FBinWrite/B=3/F=3 refnum, val
2122                ii+=1
2123                val=intw[ii]
2124                FSetPos refnum,312                                                      //tsclice ltslice
2125                FBinWrite/B=3/F=3 refnum, val
2126                ii+=1
2127                val=intw[ii]
2128                FSetPos refnum,332                                                      //extra
2129                FBinWrite/B=3/F=3 refnum, val
2130                ii+=1
2131                val=intw[ii]
2132                FSetPos refnum,336                                                      //reserve
2133                FBinWrite/B=3/F=3 refnum, val
2134                ii+=1
2135                val=intw[ii]
2136                FSetPos refnum,376                                                      //blank1
2137                FBinWrite/B=3/F=3 refnum, val
2138                ii+=1
2139                val=intw[ii]
2140                FSetPos refnum,380                                                      //blank2
2141                FBinWrite/B=3/F=3 refnum, val
2142                ii+=1
2143                val=intw[ii]
2144                FSetPos refnum,384                                                      //blank3
2145                FBinWrite/B=3/F=3 refnum, val
2146                ii+=1
2147                val=intw[ii]
2148                FSetPos refnum,458                                                      //spacer
2149                FBinWrite/B=3/F=3 refnum, val
2150                ii+=1
2151                val=intw[ii]
2152                FSetPos refnum,478                                                      //box x1
2153                FBinWrite/B=3/F=3 refnum, val
2154                ii+=1
2155                val=intw[ii]
2156                FSetPos refnum,482                                                      //box x2
2157                FBinWrite/B=3/F=3 refnum, val
2158                ii+=1
2159                val=intw[ii]
2160                FSetPos refnum,486                                                      //box y1
2161                FBinWrite/B=3/F=3 refnum, val
2162                ii+=1
2163                val=intw[ii]
2164                FSetPos refnum,490                                                      //box y2
2165                FBinWrite/B=3/F=3 refnum, val
2166               
2167                //move to the end of the file before closing
2168                FStatus refnum
2169                FSetPos refnum,V_logEOF
2170        Close refnum
2171       
2172               
2173        //VAX 4-byte FP values. No choice here but to write/read/re-write to get
2174        // the proper format. there are 52! values to write
2175        //WriteVAXReal(fullpath,rw[n],start)
2176        // [0]
2177        WriteVAXReal(fullpath,rw[0],39)
2178        WriteVAXReal(fullpath,rw[1],43)
2179        WriteVAXReal(fullpath,rw[2],47)
2180        WriteVAXReal(fullpath,rw[3],51)
2181        WriteVAXReal(fullpath,rw[4],158)
2182        WriteVAXReal(fullpath,rw[5],162)
2183        WriteVAXReal(fullpath,rw[6],166)
2184        WriteVAXReal(fullpath,rw[7],170)
2185        WriteVAXReal(fullpath,rw[8],186)
2186        WriteVAXReal(fullpath,rw[9],190)
2187        // [10]
2188        WriteVAXReal(fullpath,rw[10],220)
2189        WriteVAXReal(fullpath,rw[11],224)
2190        WriteVAXReal(fullpath,rw[12],228)
2191        WriteVAXReal(fullpath,rw[13],232)
2192        WriteVAXReal(fullpath,rw[14],236)
2193        WriteVAXReal(fullpath,rw[15],240)
2194        WriteVAXReal(fullpath,rw[16],252)
2195        WriteVAXReal(fullpath,rw[17],256)
2196        WriteVAXReal(fullpath,rw[18],260)
2197        WriteVAXReal(fullpath,rw[19],264)
2198        // [20]
2199        WriteVAXReal(fullpath,rw[20],268)
2200        WriteVAXReal(fullpath,rw[21],272)
2201        WriteVAXReal(fullpath,rw[22],276)
2202        WriteVAXReal(fullpath,rw[23],280)
2203        WriteVAXReal(fullpath,rw[24],284)
2204        WriteVAXReal(fullpath,rw[25],288)
2205        WriteVAXReal(fullpath,rw[26],292)
2206        WriteVAXReal(fullpath,rw[27],296)
2207        WriteVAXReal(fullpath,rw[28],300)
2208        WriteVAXReal(fullpath,rw[29],320)
2209        // [30]
2210        WriteVAXReal(fullpath,rw[30],324)
2211        WriteVAXReal(fullpath,rw[31],328)
2212        WriteVAXReal(fullpath,rw[32],348)
2213        WriteVAXReal(fullpath,rw[33],352)
2214        WriteVAXReal(fullpath,rw[34],356)
2215        WriteVAXReal(fullpath,rw[35],360)
2216        WriteVAXReal(fullpath,rw[36],364)
2217        WriteVAXReal(fullpath,rw[37],368)
2218        WriteVAXReal(fullpath,rw[38],372)
2219        WriteVAXReal(fullpath,rw[39],388)
2220        // [40]
2221        WriteVAXReal(fullpath,rw[40],392)
2222        WriteVAXReal(fullpath,rw[41],396)
2223        WriteVAXReal(fullpath,rw[42],400)
2224        WriteVAXReal(fullpath,rw[43],450)
2225        WriteVAXReal(fullpath,rw[44],454)
2226        WriteVAXReal(fullpath,rw[45],470)
2227        WriteVAXReal(fullpath,rw[46],474)
2228        WriteVAXReal(fullpath,rw[47],494)
2229        WriteVAXReal(fullpath,rw[48],498)
2230        WriteVAXReal(fullpath,rw[49],502)
2231        // [50]
2232        WriteVAXReal(fullpath,rw[50],506)
2233        WriteVAXReal(fullpath,rw[51],510)
2234       
2235       
2236        // write out the data
2237        Open refNum as fullpath
2238                FSetPos refnum,514                                      //  OK
2239                FBinWrite/F=2/B=3 refNum,dataWRecMarkers                //don't trust the native format
2240                FStatus refNum
2241                FSetPos refNum,V_logEOF
2242        Close refNum
2243       
2244        // all done
2245        Killwaves/Z tmpFile,dataWRecMarkers
2246       
2247        Print "Saved VAX binary data as:  ",textW[0]
2248        SetDatafolder root:
2249        return(fullpath)
2250End
2251
2252
2253Function AddRecordMarkers(in,out)
2254        Wave in,out
2255       
2256        Variable skip,ii
2257
2258//      Duplicate/O in,out
2259//      Redimension/N=16401 out
2260
2261        out=0
2262       
2263        ii=0
2264        skip=0
2265        out[ii] = 1
2266        ii+=1
2267        do
2268                if(mod(ii+skip,1022)==0)
2269                        out[ii+skip] = 0                //999999
2270                        skip+=1                 //increment AFTER filling the current marker
2271                endif
2272                out[ii+skip] = in[ii-1]
2273                ii+=1
2274        while(ii<=16384)
2275       
2276       
2277        return(0)
2278End
2279
2280
2281
2282
2283//        INTEGER*2 FUNCTION I4ToI2(I4)
2284//C
2285//C       Original author : Jim Rhyne
2286//C       Modified by     : Frank Chen 09/26/90
2287//C
2288//C       I4ToI2 = I4,                            I4 in [0,32767]
2289//C       I4ToI2 = -777,                          I4 in (2767000,...)
2290//C       I4ToI2 mapped to -13277 to -32768,      otherwise
2291//C
2292//C       the mapped values [-776,-1] and [-13276,-778] are not used
2293//C
2294//C       I4max should be 2768499, this value will maps to -32768
2295//C       and mantissa should be compared  using
2296//C               IF (R4 .GE. IPW)
2297//C       instead of
2298//C               IF (R4 .GT. (IPW - 1.0))
2299//C
2300//
2301//
2302//C       I4      :       input I*4
2303//C       R4      :       temperory real number storage
2304//C       IPW     :       IPW = IB ** ND
2305//C       NPW     :       number of power
2306//C       IB      :       Base value
2307//C       ND      :       Number of precision digits
2308//C       I4max   :       max data value w/ some error
2309//C       I2max   :       max data value w/o error
2310//C       Error   :       when data value > I4max
2311//C
2312//        INTEGER*4       I4
2313//        INTEGER*4       NPW
2314//        REAL*4          R4
2315//        INTEGER*4       IPW
2316//        INTEGER*4       IB      /10/
2317//        INTEGER*4       ND      /4/
2318//        INTEGER*4       I4max   /2767000/
2319//        INTEGER*4       I2max   /32767/
2320//        INTEGER*4       Error   /-777/
2321//
2322Function CompressI4toI2(i4)
2323        Variable i4
2324
2325        Variable npw,ipw,ib,nd,i4max,i2max,error,i4toi2
2326        Variable r4
2327       
2328        ib=10
2329        nd=4
2330        i4max=2767000
2331        i2max=32767
2332        error=-777
2333       
2334        if(i4 <= i4max)
2335                r4=i4
2336                if(r4 > i2max)
2337                        ipw = ib^nd
2338                        npw=0
2339                        do
2340                                if( !(r4 > (ipw-1)) )           //to simulate a do-while loop evaluating at top
2341                                        break
2342                                endif
2343                                npw=npw+1
2344                                r4=r4/ib               
2345                        while (1)
2346                        i4toi2 = -1*trunc(r4+ipw*npw)
2347                else
2348                        i4toi2 = trunc(r4)              //shouldn't I just return i4 (as a 2 byte value?)
2349                endif
2350        else
2351                i4toi2=error
2352        endif
2353        return(i4toi2)
2354End
2355
2356
2357// function to fill the extra bits of header information to make a "complete"
2358// simulated VAX data file.
2359//
2360//
2361Function SimulationVAXHeader(folder)
2362        String folder
2363
2364        Wave rw=root:Packages:NIST:SAS:realsRead
2365        Wave iw=root:Packages:NIST:SAS:integersRead
2366        Wave/T tw=root:Packages:NIST:SAS:textRead
2367        Wave res=root:Packages:NIST:SAS:results
2368       
2369// integers needed:
2370        //[2] count time
2371        NVAR ctTime = root:Packages:NIST:SAS:gCntTime
2372        iw[2] = ctTime
2373       
2374//reals are partially set in SASCALC initializtion
2375        //remaining values are updated automatically as SASCALC is modified
2376        // -- but still need:
2377        //      [0] monitor count
2378        //      [2] detector count (w/o beamstop)
2379        //      [4] transmission
2380        //      [5] thickness (in cm)
2381        NVAR imon = root:Packages:NIST:SAS:gImon
2382        rw[0] = imon
2383        rw[2] = res[9]
2384        rw[4] = res[8]
2385        NVAR thick = root:Packages:NIST:SAS:gThick
2386        rw[5] = thick
2387       
2388// text values needed:
2389// be sure they are padded to the correct length
2390        // [0] filename (do I fake a VAX name? probably yes...)
2391        // [1] date/time in VAX format
2392        // [2] type (use SIM)
2393        // [3] def dir (use [NG7SANS99])
2394        // [4] mode? C
2395        // [5] reserve (another date), prob not needed
2396        // [6] sample label
2397        // [9] det type "ORNL  " (6 chars)
2398       
2399        tw[1] = Secs2Date(DateTime,-2)+"  "+ Secs2Time(DateTime,3)              //20 chars, not quite VAX format
2400        tw[2] = "SIM"
2401        tw[3] = "[NG7SANS99]"
2402        tw[4] = "C"
2403        tw[5] = "01JAN09 "
2404        tw[9] = "ORNL  "
2405       
2406        NVAR index = root:Packages:NIST:SAS:gSaveIndex
2407        SVAR prefix = root:Packages:NIST:SAS:gSavePrefix
2408
2409
2410       
2411        String labelStr=" "     
2412        Variable runNum = index
2413        Prompt labelStr, "Enter sample label "          // Set prompt for x param
2414        Prompt runNum,"Run Number (automatically increments)"
2415        DoPrompt "Enter sample label", labelStr,runNum
2416        if (V_Flag)
2417                //Print "no sample label entered - no file written"
2418                //index -=1
2419                return -1                                                               // User canceled
2420        endif
2421       
2422        if(runNum != index)
2423                index = runNum
2424        endif
2425        index += 1
2426
2427        //make a three character string of the run number
2428        String numStr=""
2429        if(runNum<10)
2430                numStr = "00"+num2str(runNum)
2431        else
2432                if(runNum<100)
2433                        numStr = "0"+num2str(runNum)
2434                else
2435                        numStr = num2str(runNum)
2436                Endif
2437        Endif
2438        //date()[0] is the first letter of the day of the week
2439        // OK for most cases, except for an overnight simulation! then the suffix won't sort right...
2440//      tw[0] = prefix+numstr+".SA2_SIM_"+(date()[0])+numStr
2441
2442//fancier, JAN=A, FEB=B, etc...
2443        String timeStr= secs2date(datetime,-1)
2444        String monthStr=StringFromList(1, timeStr  ,"/")
2445
2446        tw[0] = prefix+numstr+".SA2_SIM_"+(num2char(str2num(monthStr)+64))+numStr
2447       
2448        labelStr = PadString(labelStr,60,0x20)  //60 fortran-style spaces
2449        tw[6] = labelStr[0,59]
2450       
2451        return(0)
2452End
2453
2454Function ExamineHeader(type)
2455        String type
2456
2457        String data_folder = type
2458        String dataPath = "root:Packages:NIST:"+data_folder
2459        String cur_folder = "ExamineHeader"
2460        String curPath = "root:Packages:NIST:"+cur_folder
2461       
2462        //SetDataFolder curPath
2463
2464        Wave intw=$(dataPath+":IntegersRead")
2465        Wave realw=$(dataPath+":RealsRead")
2466        Wave/T textw=$(dataPath+":TextRead")
2467        Wave logw=$(dataPath+":LogicalsRead")
2468
2469
2470        print "----------------------------------"
2471        print "Header Details"
2472        print "----------------------------------"
2473        print "fname :\t\t"+textw[0]
2474        //
2475        print "run.npre :\t\t"+num2str(intw[0])
2476        print "run.ctime :\t\t"+num2str(intw[1])
2477        print "run.rtime :\t\t"+num2str(intw[2])
2478        print "run.numruns :\t\t"+num2str(intw[3])
2479        //
2480        print "run.moncnt :\t\t"+num2str(realw[0])
2481        print "run.savmon :\t\t"+num2str(realw[1])
2482        print "run.detcnt :\t\t"+num2str(realw[2])
2483        print "run.atten :\t\t"+num2str(realw[3])       
2484        //
2485        print "run.timdat:\t\t"+textw[1]
2486        print "run.type:\t\t"+textw[2]
2487        print "run.defdir:\t\t"+textw[3]
2488        print "run.mode:\t\t"+textw[4]
2489        print "run.reserve:\t\t"+textw[5]
2490        print "sample.labl:\t\t"+textw[6]
2491        //
2492        print "sample.trns:\t\t"+num2str(realw[4])
2493        print "sample.thk:\t\t"+num2str(realw[5])
2494        print "sample.position:\t\t"+num2str(realw[6])
2495        print "sample.rotang:\t\t"+num2str(realw[7])
2496        //
2497        print "sample.table:\t\t"+num2str(intw[4])
2498        print "sample.holder:\t\t"+num2str(intw[5])
2499        print "sample.blank:\t\t"+num2str(intw[6])
2500        //
2501        print "sample.temp:\t\t"+num2str(realw[8])
2502        print "sample.field:\t\t"+num2str(realw[9])     
2503        //
2504        print "sample.tctrlr:\t\t"+num2str(intw[7])
2505        print "sample.magnet:\t\t"+num2str(intw[8])
2506        //
2507        print "sample.tunits:\t\t"+textw[7]
2508        print "sample.funits:\t\t"+textw[8]
2509        print "det.typ:\t\t"+textw[9]
2510        //
2511        print "det.calx(1):\t\t"+num2str(realw[10])
2512        print "det.calx(2):\t\t"+num2str(realw[11])
2513        print "det.calx(3):\t\t"+num2str(realw[12])
2514        print "det.caly(1):\t\t"+num2str(realw[13])
2515        print "det.caly(2):\t\t"+num2str(realw[14])
2516        print "det.caly(3):\t\t"+num2str(realw[15])
2517        //
2518        print "det.num:\t\t"+num2str(intw[9])
2519        print "det.spacer:\t\t"+num2str(intw[10])
2520        //
2521        print "det.beamx:\t\t"+num2str(realw[16])
2522        print "det.beamy:\t\t"+num2str(realw[17])
2523        print "det.dis:\t\t"+num2str(realw[18])
2524        print "det.offset:\t\t"+num2str(realw[19])
2525        print "det.siz:\t\t"+num2str(realw[20])
2526        print "det.bstop:\t\t"+num2str(realw[21])
2527        print "det.blank:\t\t"+num2str(realw[22])
2528        print "resolution.ap1:\t\t"+num2str(realw[23])
2529        print "resolution.ap2:\t\t"+num2str(realw[24])
2530        print "resolution.ap12dis:\t\t"+num2str(realw[25])
2531        print "resolution.lmda:\t\t"+num2str(realw[26])
2532        print "resolution.dlmda:\t\t"+num2str(realw[27])
2533        print "resolution.nlenses:\t\t"+num2str(realw[28])     
2534        //
2535        print "tslice.slicing:\t\t"+num2str(logw[0])
2536        //
2537        print "tslice.multfact:\t\t"+num2str(intw[11])
2538        print "tslice.ltslice:\t\t"+num2str(intw[12])
2539        //
2540        print "temp.printemp:\t\t"+num2str(logw[1])
2541        //
2542        print "temp.hold:\t\t"+num2str(realw[29])
2543        print "temp.err:\t\t"+num2str(realw[30])
2544        print "temp.blank:\t\t"+num2str(realw[31])
2545        //
2546        print "temp.extra:\t\t"+num2str(intw[13])
2547        print "temp.err:\t\t"+num2str(intw[14])
2548        //
2549        print "magnet.printmag:\t\t"+num2str(logw[2])
2550        print "magnet.sensor:\t\t"+num2str(logw[3])
2551        //
2552        print "magnet.current:\t\t"+num2str(realw[32])
2553        print "magnet.conv:\t\t"+num2str(realw[33])
2554        print "magnet.fieldlast:\t\t"+num2str(realw[34])
2555        print "magnet.blank:\t\t"+num2str(realw[35])
2556        print "magnet.spacer:\t\t"+num2str(realw[36])
2557        print "bmstp.xpos:\t\t"+num2str(realw[37])
2558        print "bmstop.ypos:\t\t"+num2str(realw[38])
2559        //     
2560        print "params.blank1:\t\t"+num2str(intw[15])
2561        print "params.blank2:\t\t"+num2str(intw[16])
2562        print "params.blank3:\t\t"+num2str(intw[17])
2563        //
2564        print "params.trnscnt:\t\t"+num2str(realw[39])
2565        print "params.extra1:\t\t"+num2str(realw[40])
2566        print "params.extra2:\t\t"+num2str(realw[41])
2567        print "params.extra3:\t\t"+num2str(realw[42])
2568        //     
2569        print "params.reserve:\t\t"+textw[10]
2570        //
2571        print "voltage.printemp:\t\t"+num2str(logw[4])
2572        //
2573        print "voltage.volts:\t\t"+num2str(realw[43])
2574        print "voltage.blank:\t\t"+num2str(realw[44])
2575        //     
2576        print "voltage.spacer:\t\t"+num2str(intw[18])
2577        //
2578        print "polarization.printpol:\t\t"+num2str(logw[5])
2579        print "polarization.flipper:\t\t"+num2str(logw[6])
2580        //     
2581        print "polarization.horiz:\t\t"+num2str(realw[45])
2582        print "polarization.vert:\t\t"+num2str(realw[46])
2583        //
2584        print "analysis.rows(1):\t\t"+num2str(intw[19])
2585        print "analysis.rows(2):\t\t"+num2str(intw[20])
2586        print "analysis.cols(1):\t\t"+num2str(intw[21])
2587        print "analysis.cols(2):\t\t"+num2str(intw[22])
2588        //
2589        print "analysis.factor:\t\t"+num2str(realw[47])
2590        print "analysis.qmin:\t\t"+num2str(realw[48])
2591        print "analysis.qmax:\t\t"+num2str(realw[49])
2592        print "analysis.imin:\t\t"+num2str(realw[50])
2593        print "analysis.imax:\t\t"+num2str(realw[51])
2594
2595End
2596
2597
2598// Sept 2009 -SRK
2599// the ICE instrument control software is not correctly writing out the file name to the header in the specific
2600// case of a file prefix less than 5 characters. ICE is quite naturally putting the blanke space(s) at the end of
2601// the string. However, the VAX puts them at the beginning...
2602Proc PatchFileNameInHeader(firstFile,lastFile)
2603        Variable firstFile=1,lastFile=100
2604
2605        fPatchFileName(firstFile,lastFile)
2606
2607End
2608
2609Proc ReadFileNameInHeader(firstFile,lastFile)
2610        Variable firstFile=1,lastFile=100
2611       
2612        fReadFileName(firstFile,lastFile)
2613End
2614
2615
2616// simple utility to patch the file name in the file headers
2617// lo is the first file number
2618// hi is the last file number (inclusive)
2619//
2620// will read the 21 character file name and put any spaces at the front of the string
2621// like the VAX does. Should have absolutely no effect if there are spaces at the
2622// beginning of the string, as the VAX does.
2623Function fPatchFileName(lo,hi)
2624        Variable lo,hi
2625       
2626        Variable ii
2627        String file,fileName
2628       
2629        //loop over all files
2630        for(ii=lo;ii<=hi;ii+=1)
2631                file = FindFileFromRunNumber(ii)
2632                if(strlen(file) != 0)
2633                        fileName = getFileName(file)
2634                        WriteFileNameToHeader(file,fileName)
2635                else
2636                        printf "run number %d not found\r",ii
2637                endif
2638        endfor
2639       
2640        return(0)
2641End
2642
2643// simple utility to read the file name stored in the file header (and the suffix)
2644Function fReadFileName(lo,hi)
2645        Variable lo,hi
2646       
2647        String file,fileName,suffix
2648        Variable ii
2649       
2650        for(ii=lo;ii<=hi;ii+=1)
2651                file = FindFileFromRunNumber(ii)
2652                if(strlen(file) != 0)
2653                        fileName = getFileName(file)
2654                        suffix = getSuffix(file)
2655                        printf "File %d:  File name = %s\t\tSuffix = %s\r",ii,fileName,suffix
2656                else
2657                        printf "run number %d not found\r",ii
2658                endif
2659        endfor
2660       
2661        return(0)
2662End
2663
2664
2665
2666
2667// April 2009 - AJJ
2668// The new ICE instrument control software was not correctly writing the run.defdir field
2669// The format of that field should be [NGxSANSn] where x is 3 or 7 and nn is 0 through 50
2670
2671Proc PatchUserAccountName(firstFile,lastFile,acctName)
2672        Variable firstFile=1,lastFile=100
2673        String acctName = "NG3SANS0"
2674
2675        fPatchUserAccountName(firstFile,lastFile,acctName)
2676
2677End
2678
2679Proc ReadUserAccountName(firstFile,lastFile)
2680        Variable firstFile=1,lastFile=100
2681       
2682        fReadUserAccountName(firstFile,lastFile)
2683End
2684
2685// simple utility to patch the user account name in the file headers
2686// pass in the account name as a string
2687// lo is the first file number
2688// hi is the last file number (inclusive)
2689//
2690Function fPatchUserAccountName(lo,hi,acctName)
2691        Variable lo,hi
2692        String acctName
2693       
2694        Variable ii
2695        String file
2696       
2697        //loop over all files
2698        for(ii=lo;ii<=hi;ii+=1)
2699                file = FindFileFromRunNumber(ii)
2700                if(strlen(file) != 0)
2701                        WriteAcctNameToHeader(file,acctName)
2702                else
2703                        printf "run number %d not found\r",ii
2704                endif
2705        endfor
2706       
2707        return(0)
2708End
2709
2710// simple utility to read the user account name stored in the file header
2711Function fReadUserAccountName(lo,hi)
2712        Variable lo,hi
2713       
2714        String file,acctName
2715        Variable ii
2716       
2717        for(ii=lo;ii<=hi;ii+=1)
2718                file = FindFileFromRunNumber(ii)
2719                if(strlen(file) != 0)
2720                        acctName = getAcctName(file)
2721                        printf "File %d:  Account name = %s\r",ii,acctName
2722                else
2723                        printf "run number %d not found\r",ii
2724                endif
2725        endfor
2726       
2727        return(0)
2728End
2729
2730// May 2009 - SRK
2731// Monitor count not written correctly to file from ICE
2732
2733Proc PatchMonitorCount(firstFile,lastFile,monCtRate)
2734        Variable firstFile=1,lastFile=100,monCtRate
2735
2736        fPatchMonitorCount(firstFile,lastFile,monCtRate)
2737
2738End
2739
2740Proc ReadMonitorCount(firstFile,lastFile)
2741        Variable firstFile=1,lastFile=100
2742       
2743        fReadMonitorCount(firstFile,lastFile)
2744End
2745
2746// simple utility to patch the user account name in the file headers
2747// pass in the account name as a string
2748// lo is the first file number
2749// hi is the last file number (inclusive)
2750//
2751Function fPatchMonitorCount(lo,hi,monCtRate)
2752        Variable lo,hi,monCtRate
2753       
2754        Variable ii,ctTime
2755        String file
2756       
2757        //loop over all files
2758        for(ii=lo;ii<=hi;ii+=1)
2759                file = FindFileFromRunNumber(ii)
2760                if(strlen(file) != 0)
2761                        ctTime = getCountTime(file)
2762                        WriteMonitorCountToHeader(file,ctTime*monCtRate)                       
2763                else
2764                        printf "run number %d not found\r",ii
2765                endif
2766        endfor
2767       
2768        return(0)
2769End
2770
2771// simple utility to read the user account name stored in the file header
2772Function fReadMonitorCount(lo,hi)
2773        Variable lo,hi
2774       
2775        String file
2776        Variable ii,monitorCount
2777       
2778        for(ii=lo;ii<=hi;ii+=1)
2779                file = FindFileFromRunNumber(ii)
2780                if(strlen(file) != 0)
2781                        monitorCount = getMonitorCount(file)
2782                        printf "File %d:  Monitor Count = %g\r",ii,monitorCount
2783                else
2784                        printf "run number %d not found\r",ii
2785                endif
2786        endfor
2787       
2788        return(0)
2789End
2790
2791
2792/////
2793Proc ReadDetectorCount(firstFile,lastFile)
2794        Variable firstFile=1,lastFile=100
2795       
2796        fReadDetectorCount(firstFile,lastFile)
2797End
2798
2799
2800// simple utility to read the detector count from the header, and the summed data value
2801// and print out the values
2802Function fReadDetectorCount(lo,hi)
2803        Variable lo,hi
2804       
2805        String file
2806        Variable ii,summed
2807       
2808        for(ii=lo;ii<=hi;ii+=1)
2809                file = FindFileFromRunNumber(ii)
2810                if(strlen(file) != 0)
2811                        ReadHeaderAndData(file)
2812                        Wave rw=root:Packages:NIST:RAW:RealsRead
2813                        Wave data=root:Packages:NIST:RAW:data                   //data as read in is linear
2814                        summed = sum(data,-inf,inf)
2815                        printf "File %d:  DetCt Header = %g\t Detector Sum = %g\t Ratio sum/hdr = %g\r",ii,rw[2],summed,summed/rw[2]
2816                else
2817                        printf "run number %d not found\r",ii
2818                endif
2819        endfor
2820       
2821        return(0)
2822End
2823
2824
2825////// OCT 2009, facility specific bits from ProDiv()
2826//"type" is the data folder that has the corrected, patched, and normalized DIV data array
2827//
2828// the header of this file is rather unimportant. Filling in a title at least would be helpful/
2829//
2830Function Write_DIV_File(type)
2831        String type
2832       
2833        // Your file writing function here. Don't try to duplicate the VAX binary format...
2834        WriteVAXWorkFile(type)
2835       
2836        return(0)
2837End
2838
2839//writes an VAX-style WORK file, "exactly" as it would be output from the VAX
2840//except for the "dummy" header and the record markers - the record marker bytes are
2841// in the files - they are just written as zeros and are meaningless
2842//file is:
2843//      516 bytes header
2844// 128x128=16384 (x4) bytes of data
2845// + 2 byte record markers interspersed just for fun
2846// = 66116 bytes
2847//prompts for name of the output file.
2848//
2849Function WriteVAXWorkFile(type)
2850        String type
2851       
2852        Wave data=$("root:Packages:NIST:"+type+":data")
2853       
2854        Variable refnum,ii=0,hdrBytes=516,a,b,offset
2855        String fullpath=""
2856       
2857        Duplicate/O data,tempData
2858        Redimension/S/N=(128*128) tempData
2859        tempData *= 4
2860       
2861        PathInfo/S catPathName
2862        fullPath = DoSaveFileDialog("Save data as")       //won't actually open the file
2863        If(cmpstr(fullPath,"")==0)
2864                //user cancel, don't write out a file
2865          Close/A
2866          Abort "no data file was written"
2867        Endif
2868       
2869        Make/B/O/N=(hdrBytes) hdrWave
2870        hdrWave=0
2871        FakeDIVHeader(hdrWave)
2872       
2873        Make/Y=2/O/N=(510) bw510                //Y=2 specifies 32 bit (=4 byte) floating point
2874        Make/Y=2/O/N=(511) bw511
2875        Make/Y=2/O/N=(48) bw48
2876
2877        Make/O/B/N=2 recWave            //two bytes
2878
2879        //actually open the file
2880        Open/C="????"/T="TEXT" refNum as fullpath
2881        FSetPos refNum, 0
2882        //write header bytes (to be skipped when reading the file later)
2883       
2884        FBinWrite /F=1 refnum,hdrWave
2885       
2886        ii=0
2887        a=0
2888        do
2889                //write 511 4-byte values (little-endian order), 4* true value
2890                bw511[] = tempData[p+a]
2891                FBinWrite /B=3/F=4 refnum,bw511
2892                a+=511
2893                //write a 2-byte record marker
2894                FBinWrite refnum,recWave
2895               
2896                //write 510 4-byte values (little-endian) 4* true value
2897                bw510[] = tempData[p+a]
2898                FBinWrite /B=3/F=4 refnum,bw510
2899                a+=510
2900               
2901                //write a 2-byte record marker
2902                FBinWrite refnum,recWave
2903               
2904                ii+=1   
2905        while(ii<16)
2906        //write out last 48  4-byte values (little-endian) 4* true value
2907        bw48[] = tempData[p+a]
2908        FBinWrite /B=3/F=4 refnum,bw48
2909        //close the file
2910        Close refnum
2911       
2912        //go back through and make it look like a VAX datafile
2913        Make/W/U/O/N=(511*2) int511             // /W=16 bit signed integers /U=unsigned
2914        Make/W/U/O/N=(510*2) int510
2915        Make/W/U/O/N=(48*2) int48
2916       
2917        //skip the header for now
2918        Open/A/T="????TEXT" refnum as fullPath
2919        FSetPos refnum,0
2920       
2921        offset=hdrBytes
2922        ii=0
2923        do
2924                //511*2 integers
2925                FSetPos refnum,offset
2926                FBinRead/B=2/F=2 refnum,int511
2927                Swap16BWave(int511)
2928                FSetPos refnum,offset
2929                FBinWrite/B=2/F=2 refnum,int511
2930               
2931                //skip 511 4-byte FP = (511*2)*2 2byte int  + 2 bytes record marker
2932                offset += 511*2*2 + 2
2933               
2934                //510*2 integers
2935                FSetPos refnum,offset
2936                FBinRead/B=2/F=2 refnum,int510
2937                Swap16BWave(int510)
2938                FSetPos refnum,offset
2939                FBinWrite/B=2/F=2 refnum,int510
2940               
2941                //
2942                offset += 510*2*2 + 2
2943               
2944                ii+=1
2945        while(ii<16)
2946        //48*2 integers
2947        FSetPos refnum,offset
2948        FBinRead/B=2/F=2 refnum,int48
2949        Swap16BWave(int48)
2950        FSetPos refnum,offset
2951        FBinWrite/B=2/F=2 refnum,int48
2952
2953        //move to EOF and close
2954        FStatus refnum
2955        FSetPos refnum,V_logEOF
2956       
2957        Close refnum
2958       
2959        Killwaves/Z hdrWave,bw48,bw511,bw510,recWave,temp16,int511,int510,int48
2960End
2961
2962// given a 16 bit integer wave, read in as 2-byte pairs of 32-bit FP data
2963// swap the order of the 2-byte pairs
2964//
2965Function Swap16BWave(w)
2966        Wave w
2967
2968        Duplicate/O w,temp16
2969        //Variable num=numpnts(w),ii=0
2970
2971        //elegant way to swap even/odd values, using wave assignments
2972        w[0,*;2] = temp16[p+1]
2973        w[1,*;2] = temp16[p-1]
2974
2975//crude way, using a loop       
2976//      for(ii=0;ii<num;ii+=2)
2977//              w[ii] = temp16[ii+1]
2978//              w[ii+1] = temp16[ii]
2979//      endfor
2980       
2981        return(0)       
2982End
2983
2984// writes a fake label into the header of the DIV file
2985//
2986Function FakeDIVHeader(hdrWave)
2987        WAVE hdrWave
2988       
2989        //put some fake text into the sample label position (60 characters=60 bytes)
2990        String day=date(),tim=time(),lbl=""
2991        Variable start=98,num,ii
2992       
2993        lbl = "Sensitivity (DIV) created "+day +" "+tim
2994        num=strlen(lbl)
2995        for(ii=0;ii<num;ii+=1)
2996                hdrWave[start+ii] = char2num(lbl[ii])
2997        endfor
2998
2999        return(0)
3000End
3001
3002////////end of ProDiv() specifics
Note: See TracBrowser for help on using the repository browser.