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

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

Update to CatVSTable to show sample position, TISANE to fix a couple of startup bugs and FuzzySpheres? to add the lorentzian term.

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