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

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

A variety of changes to get some of the basic reduction functions working with HFIR raw data files.

Patch now works correctly without duplicating file names in the popup list.

Transmissions can be assigned and calculated now that I've changed the critera for deciding if a file is a transmission file. Hopefully this will always work - it's based on the beamstop y-position being less than 30 mm for all four beam stops.

When checking for a DIV file, it returns an OK if the extension is .xml, since the raw data and div files can't be distinguished like the binary VAX data.

The file catalog is correct, but still excruciatingly slow.

File size: 74.8 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//temperature is at byte 186
1519Function getTemperature(fname)
1520        String fname
1521       
1522        return(getRealValueFromHeader(fname,186))
1523end
1524
1525//field strength is at byte 190
1526// 190 is not the right location, 348 looks to be correct for the electromagnets, 450 for the
1527// superconducting magnet. Although each place is only the voltage, it is correct
1528Function getFieldStrength(fname)
1529        String fname
1530       
1531//      return(getRealValueFromHeader(fname,190))
1532        return(getRealValueFromHeader(fname,348))
1533end
1534
1535//beam xPos is at byte 252
1536Function getBeamXPos(fname)
1537        String fname
1538       
1539        return(getRealValueFromHeader(fname,252))
1540end
1541
1542//beam Y pos is at byte 256
1543Function getBeamYPos(fname)
1544        String fname
1545       
1546        return(getRealValueFromHeader(fname,256))
1547end
1548
1549//sample to detector distance is at byte 260
1550Function getSDD(fname)
1551        String fname
1552       
1553        return(getRealValueFromHeader(fname,260))
1554end
1555
1556//detector offset is at byte 264
1557Function getDetectorOffset(fname)
1558        String fname
1559       
1560        return(getRealValueFromHeader(fname,264))
1561end
1562
1563//Beamstop diameter is at byte 272
1564Function getBSDiameter(fname)
1565        String fname
1566       
1567        return(getRealValueFromHeader(fname,272))
1568end
1569
1570//source aperture diameter is at byte 280
1571Function getSourceApertureDiam(fname)
1572        String fname
1573       
1574        return(getRealValueFromHeader(fname,280))
1575end
1576
1577//sample aperture diameter is at byte 284
1578Function getSampleApertureDiam(fname)
1579        String fname
1580       
1581        return(getRealValueFromHeader(fname,284))
1582end
1583
1584//source AP to Sample AP distance is at byte 288
1585Function getSourceToSampleDist(fname)
1586        String fname
1587       
1588        return(getRealValueFromHeader(fname,288))
1589end
1590
1591//wavelength is at byte 292
1592Function getWavelength(fname)
1593        String fname
1594       
1595        return(getRealValueFromHeader(fname,292))
1596end
1597
1598//wavelength spread is at byte 296
1599Function getWavelengthSpread(fname)
1600        String fname
1601       
1602        return(getRealValueFromHeader(fname,296))
1603end
1604
1605//transmission detector count is at byte 388
1606Function getTransDetectorCounts(fname)
1607        String fname
1608       
1609        return(getRealValueFromHeader(fname,388))
1610end
1611
1612//detector pixel X size is at byte 220
1613Function getDetectorPixelXSize(fname)
1614        String fname
1615       
1616        return(getRealValueFromHeader(fname,220))
1617end
1618
1619//detector pixel Y size is at byte 232
1620Function getDetectorPixelYSize(fname)
1621        String fname
1622       
1623        return(getRealValueFromHeader(fname,232))
1624end
1625
1626// stub for ILL - power is written to their header, not ours
1627Function getReactorPower(fname)
1628        String fname
1629
1630        return 0
1631
1632end
1633
1634//////  integer values
1635
1636Function getIntegerFromHeader(fname,start)
1637        String fname                            //full path:name
1638        Variable start          //starting byte
1639       
1640        Variable refnum,val
1641        Open/R refNum as fname
1642        FSetPos refNum,start
1643        FBinRead/B=3/F=3 refnum,val
1644        Close refnum
1645       
1646        return(val)
1647End
1648
1649//total count time is at byte 31       
1650Function getCountTime(fname)
1651        String fname
1652        return(getIntegerFromHeader(fname,31))
1653end
1654
1655
1656//reads the wavelength from a reduced data file (not very reliable)
1657// - does not work with NSORTed files
1658// - only used in FIT/RPA (which itself is almost NEVER used...)
1659//
1660Function GetLambdaFromReducedData(tempName)
1661        String tempName
1662       
1663        String junkString
1664        Variable lambdaFromFile, fileVar
1665        lambdaFromFile = 6.0
1666        Open/R/P=catPathName fileVar as tempName
1667        FReadLine fileVar, junkString
1668        FReadLine fileVar, junkString
1669        FReadLine fileVar, junkString
1670        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
1671                FReadLine/N=11 fileVar, junkString
1672                FReadLine/N=10 fileVar, junkString
1673                lambdaFromFile = str2num(junkString)
1674        endif
1675        Close fileVar
1676       
1677        return(lambdaFromFile)
1678End
1679
1680/////   TRANSMISSION RELATED FUNCTIONS    ////////
1681//box coordinate are returned by reference
1682// filename is the full path:name
1683Function getXYBoxFromFile(filename,x1,x2,y1,y2)
1684        String filename
1685        Variable &x1,&x2,&y1,&y2
1686       
1687        Variable refnum
1688//      String tmpFile = FindValidFilename(filename)
1689               
1690//      Open/R/P=catPathName refnum as tmpFile
1691        Open/R refnum as filename
1692        FSetPos refnum,478
1693        FBinRead/F=3/B=3 refnum, x1
1694        FBinRead/F=3/B=3 refnum, x2
1695        FBinRead/F=3/B=3 refnum, y1
1696        FBinRead/F=3/B=3 refnum, y2
1697        Close refnum
1698       
1699        return(0)
1700End
1701
1702//go find the file, open it and write 4 integers to the file
1703//in the positions for analysis.rows(2), .cols(2) = 4 unused 4byte integers
1704Function WriteXYBoxToHeader(filename,x1,x2,y1,y2)
1705        String filename
1706        Variable x1,x2,y1,y2
1707       
1708        Variable refnum
1709        Open/A/T="????TEXT" refnum as filename
1710        FSetPos refnum,478
1711        FBinWrite/F=3/B=3 refNum, x1
1712        FBinWrite/F=3/B=3 refNum, x2
1713        FBinWrite/F=3/B=3 refNum, y1
1714        FBinWrite/F=3/B=3 refNum, y2
1715        //move to the end of the file before closing
1716        FStatus refnum
1717        FSetPos refnum,V_logEOF
1718        Close refnum
1719       
1720        return(0)
1721End
1722
1723//associated file suffix is the first 4 characters of a text field starting
1724// at byte 404
1725// suffix must be four characters long, if not, it's truncated
1726//
1727Function WriteAssocFileSuffixToHeader(fname,suffix)
1728        String fname,suffix
1729               
1730        suffix = suffix[0,3]            //limit to 4 characters
1731        WriteTextToHeader(fname,suffix,404)
1732       
1733        return(0)
1734end
1735
1736
1737// Jan 2008
1738// it has been determined that the true pixel dimension of the ordela detectors is not 5.0 mm
1739// but somewhat larger (5.08? mm). "new" data files will be written out with the proper size
1740// and old files will be patched batchwise to put the prpoer value in the header
1741
1742Proc PatchDetectorPixelSize(firstFile,lastFile,XSize,YSize)
1743        Variable firstFile=1,lastFile=100,XSize=5.08,YSize=5.08
1744
1745        fPatchDetectorPixelSize(firstFile,lastFile,XSize,YSize)
1746
1747End
1748
1749Proc ReadDetectorPixelSize(firstFile,lastFile)
1750        Variable firstFile=1,lastFile=100
1751       
1752        fReadDetectorPixelSize(firstFile,lastFile)
1753End
1754
1755// simple utility to patch the detector pixel size in the file headers
1756// pass in the dimensions in mm
1757// lo is the first file number
1758// hi is the last file number (inclusive)
1759//
1760Function fPatchDetectorPixelSize(lo,hi,xdim,ydim)
1761        Variable lo,hi,xdim,ydim
1762       
1763        Variable ii
1764        String file
1765       
1766        //loop over all files
1767        for(ii=lo;ii<=hi;ii+=1)
1768                file = FindFileFromRunNumber(ii)
1769                if(strlen(file) != 0)
1770                        WriteDetPixelXToHeader(file,xdim)
1771                        WriteDetPixelyToHeader(file,ydim)
1772                else
1773                        printf "run number %d not found\r",ii
1774                endif
1775        endfor
1776       
1777        return(0)
1778End
1779
1780// simple utility to read the pixel size stored in the file header
1781Function fReadDetectorPixelSize(lo,hi)
1782        Variable lo,hi
1783       
1784        String file
1785        Variable xdim,ydim,ii
1786       
1787        for(ii=lo;ii<=hi;ii+=1)
1788                file = FindFileFromRunNumber(ii)
1789                if(strlen(file) != 0)
1790                        xdim = getDetectorPixelXSize(file)
1791                        ydim = getDetectorPixelYSize(file)
1792                        printf "File %d:  Pixel dimensions (mm): X = %g\t Y = %g\r",ii,xdim,ydim
1793                else
1794                        printf "run number %d not found\r",ii
1795                endif
1796        endfor
1797       
1798        return(0)
1799End
1800
1801
1802
1803//*******************
1804//************
1805// simple command - line utilities to convert/unconvert the header value
1806// that flags files as using lenses
1807//
1808// stored in reals[28], header byte start @ 300
1809//
1810// currently, two values (0 | 1) = (no lens | yes lens)
1811// ideally, this field will have the actual number of lenses inserted.
1812//
1813// this is used in getResolution (reads the reals[]) and switches the calculation
1814//************
1815
1816Proc ConvertToLens(RunNumber)
1817        Variable RunNumber
1818        HeaderToLensResolution(RunNumber)
1819End
1820
1821Proc ConvertToPinhole(RunNumber)
1822        Variable RunNumber
1823        HeaderToPinholeResolution(RunNumber)
1824End
1825
1826// sets the flag to zero in the file (= 0)
1827Function HeaderToPinholeResolution(num)
1828        Variable num   
1829       
1830        //Print "UnConvert"
1831        String fullname=""
1832       
1833        fullname = FindFileFromRunNumber(num)
1834        Print fullname
1835        //report error or change the file
1836        if(cmpstr(fullname,"")==0)
1837                Print "HeaderToPinhole - file not found"
1838        else
1839                //Print "Unconvert",fullname
1840                WriteVAXReal(fullname,0,300)
1841        Endif
1842        return(0)
1843End
1844
1845// sets the flag to one in the file (= 1)
1846Function HeaderToLensResolution(num)
1847        Variable num   
1848       
1849        //Print "UnConvert"
1850        String fullname=""
1851       
1852        fullname = FindFileFromRunNumber(num)
1853        Print fullname
1854        //report error or change the file
1855        if(cmpstr(fullname,"")==0)
1856                Print "HeaderToPinhole - file not found"
1857        else
1858                //Print "Unconvert",fullname
1859                WriteVAXReal(fullname,1,300)
1860        Endif
1861        return(0)
1862End
1863
1864
1865////// OCT 2009, facility specific bits from MonteCarlo functions()
1866//"type" is the data folder that has the data array that is to be (re)written as a full
1867// data file, as if it was a raw data file
1868//
1869Function/S Write_RawData_File(type,fullpath,dialog)
1870        String type,fullpath
1871        Variable dialog         //=1 will present dialog for name
1872
1873        String filename = ""
1874        filename = Write_VAXRaw_Data(type,fullpath,dialog)
1875       
1876        return(filename)
1877End
1878
1879// given a data folder, write out the corresponding VAX binary data file.
1880//
1881// I don't think that I can generate a STRUCT and then lay that down - since the
1882// VAX FP format has to be duplicated with a write/read/flip/re-write dance...
1883//
1884// seems to work correctly byte for byte
1885// compression has bee implmented also, for complete replication of the format (n>32767 in a cell)
1886//
1887// SRK 29JAN09
1888//
1889// other functions needed:
1890//
1891//
1892// one to generate a fake data file name, and put the matching name in the data header
1893// !! must fake the Annn suffix too! this is used...
1894// use a prefix, keep a run number, initials SIM, and alpha as before (start randomly, don't bother changing?)
1895//
1896// for right now, keep a run number, and generate
1897// PREFIXnnn.SA2_SIM_Annn
1898// also, start the index @ 100 to avoid leading zeros (although I have the functions available)
1899
1900// one to generate the date/time string in VAX format, right # characters// Print Secs2Time(DateTime,3)                         // Prints 13:07:29
1901// Print Secs2Time(DateTime,3)                          // Prints 13:07:29
1902//      Print Secs2Date(DateTime,-2)            // 1993-03-14                   //this call is independent of System date/time!//
1903//
1904//
1905// simulation should call as ("SAS","",0) to bypass the dialog, and to fill the header
1906// this could be modified in the future to be more generic
1907//
1908///
1909// changed to return the string w/ the filename as written for later use
1910Function/S Write_VAXRaw_Data(type,fullpath,dialog)
1911        String type,fullpath
1912        Variable dialog         //=1 will present dialog for name
1913       
1914        String destStr=""
1915        Variable refNum,ii,val,err
1916       
1917       
1918        destStr = "root:Packages:NIST:"+type
1919       
1920        SetDataFolder $destStr
1921        WAVE intw=integersRead
1922        WAVE rw=realsRead
1923        WAVE/T textw=textRead
1924        WAVE data=linear_data
1925       
1926        //check each wave
1927        If(!(WaveExists(intw)))
1928                Abort "intw DNExist WriteVAXData()"
1929        Endif
1930        If(!(WaveExists(rw)))
1931                Abort "rw DNExist WriteVAXData()"
1932        Endif
1933        If(!(WaveExists(textw)))
1934                Abort "textw DNExist WriteVAXData()"
1935        Endif
1936        If(!(WaveExists(data)))
1937                Abort "linear_data DNExist WriteVAXData()"
1938        Endif
1939       
1940       
1941//      if(dialog)
1942//              PathInfo/S catPathName
1943//              fullPath = DoSaveFileDialog("Save data as")
1944//              If(cmpstr(fullPath,"")==0)
1945//                      //user cancel, don't write out a file
1946//                      Close/A
1947//                      Abort "no data file was written"
1948//              Endif
1949//              //Print "dialog fullpath = ",fullpath
1950//      Endif
1951       
1952        // save to home, or get out
1953        //
1954        PathInfo home
1955        if(V_flag       == 0)
1956                Abort "no save path defined. Save the experiment to generate a home path"
1957        endif
1958       
1959        fullPath = S_path               //not the full path yet, still need the name, after the header is filled
1960       
1961       
1962        Make/O/B/U/N=33316 tmpFile              //unsigned integers for a blank data file
1963        tmpFile=0
1964       
1965        Make/O/W/N=16401 dataWRecMarkers
1966        AddRecordMarkers(data,dataWRecMarkers)
1967       
1968        // need to re-compress?? maybe never a problem, but should be done for the odd case
1969        dataWRecMarkers = CompressI4toI2(dataWRecMarkers)               //unless a pixel value is > 32767, the same values are returned
1970       
1971        // fill the last bits of the header information
1972        err = SimulationVAXHeader(type)
1973        if (err == -1)
1974                Abort "no sample label entered - no file written"                       // User did not fill in header correctly/completely
1975        endif
1976        fullPath = fullPath + textW[0]
1977       
1978        // lay down a blank file
1979        Open refNum as fullpath
1980                FBinWrite refNum,tmpFile                        //file is the right size, but all zeroes
1981        Close refNum
1982       
1983        // fill up the header
1984        // text values
1985        // elements of textW are already the correct length set by the read, but just make sure
1986        String str
1987       
1988        if(strlen(textw[0])>21)
1989                textw[0] = (textw[0])[0,20]
1990        endif
1991        if(strlen(textw[1])>20)
1992                textw[1] = (textw[1])[0,19]
1993        endif
1994        if(strlen(textw[2])>3)
1995                textw[2] = (textw[2])[0,2]
1996        endif
1997        if(strlen(textw[3])>11)
1998                textw[3] = (textw[3])[0,10]
1999        endif
2000        if(strlen(textw[4])>1)
2001                textw[4] = (textw[4])[0]
2002        endif
2003        if(strlen(textw[5])>8)
2004                textw[5] = (textw[5])[0,7]
2005        endif
2006        if(strlen(textw[6])>60)
2007                textw[6] = (textw[6])[0,59]
2008        endif
2009        if(strlen(textw[7])>6)
2010                textw[7] = (textw[7])[0,5]
2011        endif
2012        if(strlen(textw[8])>6)
2013                textw[8] = (textw[8])[0,5]
2014        endif
2015        if(strlen(textw[9])>6)
2016                textw[9] = (textw[9])[0,5]
2017        endif
2018        if(strlen(textw[10])>42)
2019                textw[10] = (textw[10])[0,41]
2020        endif   
2021       
2022        ii=0
2023        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
2024                str = textW[ii]
2025                FSetPos refnum,2                                                        ////file name
2026                FBinWrite/F=0 refnum, str      //native object format (character)
2027                ii+=1
2028                str = textW[ii]
2029                FSetPos refnum,55                                                       ////date/time
2030                FBinWrite/F=0 refnum, str
2031                ii+=1
2032                str = textW[ii]
2033                FSetPos refnum,75                                                       ////type
2034                FBinWrite/F=0 refnum, str
2035                ii+=1
2036                str = textW[ii]
2037                FSetPos refnum,78                                               ////def dir
2038                FBinWrite/F=0 refnum, str
2039                ii+=1
2040                str = textW[ii]
2041                FSetPos refnum,89                                               ////mode
2042                FBinWrite/F=0 refnum, str
2043                ii+=1
2044                str = textW[ii]
2045                FSetPos refnum,90                                               ////reserve
2046                FBinWrite/F=0 refnum, str
2047                ii+=1
2048                str = textW[ii]
2049                FSetPos refnum,98                                               ////@98, sample label
2050                FBinWrite/F=0 refnum, str
2051                ii+=1
2052                str = textW[ii]
2053                FSetPos refnum,202                                              //// T units
2054                FBinWrite/F=0 refnum, str
2055                ii+=1
2056                str = textW[ii]
2057                FSetPos refnum,208                                              //// F units
2058                FBinWrite/F=0 refnum, str
2059                ii+=1
2060                str = textW[ii]
2061                FSetPos refnum,214                                              ////det type
2062                FBinWrite/F=0 refnum, str
2063                ii+=1
2064                str = textW[ii]
2065                FSetPos refnum,404                                              ////reserve
2066                FBinWrite/F=0 refnum, str
2067       
2068                //move to the end of the file before closing
2069                FStatus refnum
2070                FSetPos refnum,V_logEOF
2071        Close refnum
2072       
2073       
2074        // integer values (4 bytes)
2075        ii=0
2076        Open/A/T="????TEXT" refnum as fullpath      //Open for writing! Move to EOF before closing!
2077                val = intw[ii]
2078                FSetPos refnum,23                                                       //nprefactors
2079                FBinWrite/B=3/F=3 refnum, val      //write a 4-byte integer
2080                ii+=1
2081                val=intw[ii]
2082                FSetPos refnum,27                                                       //ctime
2083                FBinWrite/B=3/F=3 refnum, val
2084                ii+=1
2085                val=intw[ii]
2086                FSetPos refnum,31                                                       //rtime
2087                FBinWrite/B=3/F=3 refnum, val
2088                ii+=1
2089                val=intw[ii]
2090                FSetPos refnum,35                                                       //numruns
2091                FBinWrite/B=3/F=3 refnum, val
2092                ii+=1
2093                val=intw[ii]
2094                FSetPos refnum,174                                                      //table
2095                FBinWrite/B=3/F=3 refnum, val
2096                ii+=1
2097                val=intw[ii]
2098                FSetPos refnum,178                                                      //holder
2099                FBinWrite/B=3/F=3 refnum, val
2100                ii+=1
2101                val=intw[ii]
2102                FSetPos refnum,182                                                      //blank
2103                FBinWrite/B=3/F=3 refnum, val
2104                ii+=1
2105                val=intw[ii]
2106                FSetPos refnum,194                                                      //tctrlr
2107                FBinWrite/B=3/F=3 refnum, val
2108                ii+=1
2109                val=intw[ii]
2110                FSetPos refnum,198                                                      //magnet
2111                FBinWrite/B=3/F=3 refnum, val
2112                ii+=1
2113                val=intw[ii]
2114                FSetPos refnum,244                                                      //det num
2115                FBinWrite/B=3/F=3 refnum, val
2116                ii+=1
2117                val=intw[ii]
2118                FSetPos refnum,248                                                      //det spacer
2119                FBinWrite/B=3/F=3 refnum, val
2120                ii+=1
2121                val=intw[ii]
2122                FSetPos refnum,308                                                      //tslice mult
2123                FBinWrite/B=3/F=3 refnum, val
2124                ii+=1
2125                val=intw[ii]
2126                FSetPos refnum,312                                                      //tsclice ltslice
2127                FBinWrite/B=3/F=3 refnum, val
2128                ii+=1
2129                val=intw[ii]
2130                FSetPos refnum,332                                                      //extra
2131                FBinWrite/B=3/F=3 refnum, val
2132                ii+=1
2133                val=intw[ii]
2134                FSetPos refnum,336                                                      //reserve
2135                FBinWrite/B=3/F=3 refnum, val
2136                ii+=1
2137                val=intw[ii]
2138                FSetPos refnum,376                                                      //blank1
2139                FBinWrite/B=3/F=3 refnum, val
2140                ii+=1
2141                val=intw[ii]
2142                FSetPos refnum,380                                                      //blank2
2143                FBinWrite/B=3/F=3 refnum, val
2144                ii+=1
2145                val=intw[ii]
2146                FSetPos refnum,384                                                      //blank3
2147                FBinWrite/B=3/F=3 refnum, val
2148                ii+=1
2149                val=intw[ii]
2150                FSetPos refnum,458                                                      //spacer
2151                FBinWrite/B=3/F=3 refnum, val
2152                ii+=1
2153                val=intw[ii]
2154                FSetPos refnum,478                                                      //box x1
2155                FBinWrite/B=3/F=3 refnum, val
2156                ii+=1
2157                val=intw[ii]
2158                FSetPos refnum,482                                                      //box x2
2159                FBinWrite/B=3/F=3 refnum, val
2160                ii+=1
2161                val=intw[ii]
2162                FSetPos refnum,486                                                      //box y1
2163                FBinWrite/B=3/F=3 refnum, val
2164                ii+=1
2165                val=intw[ii]
2166                FSetPos refnum,490                                                      //box y2
2167                FBinWrite/B=3/F=3 refnum, val
2168               
2169                //move to the end of the file before closing
2170                FStatus refnum
2171                FSetPos refnum,V_logEOF
2172        Close refnum
2173       
2174               
2175        //VAX 4-byte FP values. No choice here but to write/read/re-write to get
2176        // the proper format. there are 52! values to write
2177        //WriteVAXReal(fullpath,rw[n],start)
2178        // [0]
2179        WriteVAXReal(fullpath,rw[0],39)
2180        WriteVAXReal(fullpath,rw[1],43)
2181        WriteVAXReal(fullpath,rw[2],47)
2182        WriteVAXReal(fullpath,rw[3],51)
2183        WriteVAXReal(fullpath,rw[4],158)
2184        WriteVAXReal(fullpath,rw[5],162)
2185        WriteVAXReal(fullpath,rw[6],166)
2186        WriteVAXReal(fullpath,rw[7],170)
2187        WriteVAXReal(fullpath,rw[8],186)
2188        WriteVAXReal(fullpath,rw[9],190)
2189        // [10]
2190        WriteVAXReal(fullpath,rw[10],220)
2191        WriteVAXReal(fullpath,rw[11],224)
2192        WriteVAXReal(fullpath,rw[12],228)
2193        WriteVAXReal(fullpath,rw[13],232)
2194        WriteVAXReal(fullpath,rw[14],236)
2195        WriteVAXReal(fullpath,rw[15],240)
2196        WriteVAXReal(fullpath,rw[16],252)
2197        WriteVAXReal(fullpath,rw[17],256)
2198        WriteVAXReal(fullpath,rw[18],260)
2199        WriteVAXReal(fullpath,rw[19],264)
2200        // [20]
2201        WriteVAXReal(fullpath,rw[20],268)
2202        WriteVAXReal(fullpath,rw[21],272)
2203        WriteVAXReal(fullpath,rw[22],276)
2204        WriteVAXReal(fullpath,rw[23],280)
2205        WriteVAXReal(fullpath,rw[24],284)
2206        WriteVAXReal(fullpath,rw[25],288)
2207        WriteVAXReal(fullpath,rw[26],292)
2208        WriteVAXReal(fullpath,rw[27],296)
2209        WriteVAXReal(fullpath,rw[28],300)
2210        WriteVAXReal(fullpath,rw[29],320)
2211        // [30]
2212        WriteVAXReal(fullpath,rw[30],324)
2213        WriteVAXReal(fullpath,rw[31],328)
2214        WriteVAXReal(fullpath,rw[32],348)
2215        WriteVAXReal(fullpath,rw[33],352)
2216        WriteVAXReal(fullpath,rw[34],356)
2217        WriteVAXReal(fullpath,rw[35],360)
2218        WriteVAXReal(fullpath,rw[36],364)
2219        WriteVAXReal(fullpath,rw[37],368)
2220        WriteVAXReal(fullpath,rw[38],372)
2221        WriteVAXReal(fullpath,rw[39],388)
2222        // [40]
2223        WriteVAXReal(fullpath,rw[40],392)
2224        WriteVAXReal(fullpath,rw[41],396)
2225        WriteVAXReal(fullpath,rw[42],400)
2226        WriteVAXReal(fullpath,rw[43],450)
2227        WriteVAXReal(fullpath,rw[44],454)
2228        WriteVAXReal(fullpath,rw[45],470)
2229        WriteVAXReal(fullpath,rw[46],474)
2230        WriteVAXReal(fullpath,rw[47],494)
2231        WriteVAXReal(fullpath,rw[48],498)
2232        WriteVAXReal(fullpath,rw[49],502)
2233        // [50]
2234        WriteVAXReal(fullpath,rw[50],506)
2235        WriteVAXReal(fullpath,rw[51],510)
2236       
2237       
2238        // write out the data
2239        Open refNum as fullpath
2240                FSetPos refnum,514                                      //  OK
2241                FBinWrite/F=2/B=3 refNum,dataWRecMarkers                //don't trust the native format
2242                FStatus refNum
2243                FSetPos refNum,V_logEOF
2244        Close refNum
2245       
2246        // all done
2247        Killwaves/Z tmpFile,dataWRecMarkers
2248       
2249        Print "Saved VAX binary data as:  ",textW[0]
2250        SetDatafolder root:
2251        return(fullpath)
2252End
2253
2254
2255Function AddRecordMarkers(in,out)
2256        Wave in,out
2257       
2258        Variable skip,ii
2259
2260//      Duplicate/O in,out
2261//      Redimension/N=16401 out
2262
2263        out=0
2264       
2265        ii=0
2266        skip=0
2267        out[ii] = 1
2268        ii+=1
2269        do
2270                if(mod(ii+skip,1022)==0)
2271                        out[ii+skip] = 0                //999999
2272                        skip+=1                 //increment AFTER filling the current marker
2273                endif
2274                out[ii+skip] = in[ii-1]
2275                ii+=1
2276        while(ii<=16384)
2277       
2278       
2279        return(0)
2280End
2281
2282
2283
2284
2285//        INTEGER*2 FUNCTION I4ToI2(I4)
2286//C
2287//C       Original author : Jim Rhyne
2288//C       Modified by     : Frank Chen 09/26/90
2289//C
2290//C       I4ToI2 = I4,                            I4 in [0,32767]
2291//C       I4ToI2 = -777,                          I4 in (2767000,...)
2292//C       I4ToI2 mapped to -13277 to -32768,      otherwise
2293//C
2294//C       the mapped values [-776,-1] and [-13276,-778] are not used
2295//C
2296//C       I4max should be 2768499, this value will maps to -32768
2297//C       and mantissa should be compared  using
2298//C               IF (R4 .GE. IPW)
2299//C       instead of
2300//C               IF (R4 .GT. (IPW - 1.0))
2301//C
2302//
2303//
2304//C       I4      :       input I*4
2305//C       R4      :       temperory real number storage
2306//C       IPW     :       IPW = IB ** ND
2307//C       NPW     :       number of power
2308//C       IB      :       Base value
2309//C       ND      :       Number of precision digits
2310//C       I4max   :       max data value w/ some error
2311//C       I2max   :       max data value w/o error
2312//C       Error   :       when data value > I4max
2313//C
2314//        INTEGER*4       I4
2315//        INTEGER*4       NPW
2316//        REAL*4          R4
2317//        INTEGER*4       IPW
2318//        INTEGER*4       IB      /10/
2319//        INTEGER*4       ND      /4/
2320//        INTEGER*4       I4max   /2767000/
2321//        INTEGER*4       I2max   /32767/
2322//        INTEGER*4       Error   /-777/
2323//
2324Function CompressI4toI2(i4)
2325        Variable i4
2326
2327        Variable npw,ipw,ib,nd,i4max,i2max,error,i4toi2
2328        Variable r4
2329       
2330        ib=10
2331        nd=4
2332        i4max=2767000
2333        i2max=32767
2334        error=-777
2335       
2336        if(i4 <= i4max)
2337                r4=i4
2338                if(r4 > i2max)
2339                        ipw = ib^nd
2340                        npw=0
2341                        do
2342                                if( !(r4 > (ipw-1)) )           //to simulate a do-while loop evaluating at top
2343                                        break
2344                                endif
2345                                npw=npw+1
2346                                r4=r4/ib               
2347                        while (1)
2348                        i4toi2 = -1*trunc(r4+ipw*npw)
2349                else
2350                        i4toi2 = trunc(r4)              //shouldn't I just return i4 (as a 2 byte value?)
2351                endif
2352        else
2353                i4toi2=error
2354        endif
2355        return(i4toi2)
2356End
2357
2358
2359// function to fill the extra bits of header information to make a "complete"
2360// simulated VAX data file.
2361//
2362// NCNR-Specific
2363//
2364Function SimulationVAXHeader(folder)
2365        String folder
2366
2367        Wave rw=root:Packages:NIST:SAS:realsRead
2368        Wave iw=root:Packages:NIST:SAS:integersRead
2369        Wave/T tw=root:Packages:NIST:SAS:textRead
2370        Wave res=root:Packages:NIST:SAS:results
2371       
2372// integers needed:
2373        //[2] count time
2374        NVAR ctTime = root:Packages:NIST:SAS:gCntTime
2375        iw[2] = ctTime
2376       
2377//reals are partially set in SASCALC initializtion
2378        //remaining values are updated automatically as SASCALC is modified
2379        // -- but still need:
2380        //      [0] monitor count
2381        //      [2] detector count (w/o beamstop)
2382        //      [4] transmission
2383        //      [5] thickness (in cm)
2384        NVAR imon = root:Packages:NIST:SAS:gImon
2385        rw[0] = imon
2386        rw[2] = res[9]
2387        rw[4] = res[8]
2388        NVAR thick = root:Packages:NIST:SAS:gThick
2389        rw[5] = thick
2390       
2391// text values needed:
2392// be sure they are padded to the correct length
2393        // [0] filename (do I fake a VAX name? probably yes...)
2394        // [1] date/time in VAX format
2395        // [2] type (use SIM)
2396        // [3] def dir (use [NG7SANS99])
2397        // [4] mode? C
2398        // [5] reserve (another date), prob not needed
2399        // [6] sample label
2400        // [9] det type "ORNL  " (6 chars)
2401       
2402        tw[1] = Secs2Date(DateTime,-2)+"  "+ Secs2Time(DateTime,3)              //20 chars, not quite VAX format
2403        tw[2] = "SIM"
2404        tw[3] = "[NG7SANS99]"
2405        tw[4] = "C"
2406        tw[5] = "01JAN09 "
2407        tw[9] = "ORNL  "
2408       
2409       
2410        //get the run index and the sample label from the optional parameters, or from a dialog
2411        NVAR index = root:Packages:NIST:SAS:gSaveIndex
2412        SVAR prefix = root:Packages:NIST:SAS:gSavePrefix
2413// did the user pass in values?
2414        NVAR autoSaveIndex = root:Packages:NIST:SAS:gAutoSaveIndex
2415        SVAR autoSaveLabel = root:Packages:NIST:SAS:gAutoSaveLabel
2416       
2417        String labelStr=""     
2418        Variable runNum
2419        if( (autoSaveIndex != 0) && (strlen(autoSaveLabel) > 0) )
2420                // all is OK, proceed with the save
2421                labelStr = autoSaveLabel
2422                runNum = autoSaveIndex          //user must take care of incrementing this!
2423        else
2424                //one or the other, or both are missing, so ask
2425                runNum = index
2426                Prompt labelStr, "Enter sample label "          // Set prompt for x param
2427                Prompt runNum,"Run Number (automatically increments)"
2428                DoPrompt "Enter sample label", labelStr,runNum
2429                if (V_Flag)
2430                        //Print "no sample label entered - no file written"
2431                        //index -=1
2432                        return -1                                                               // User canceled
2433                endif
2434                if(runNum != index)
2435                        index = runNum
2436                endif
2437                index += 1
2438        endif
2439       
2440
2441
2442        //make a three character string of the run number
2443        String numStr=""
2444        if(runNum<10)
2445                numStr = "00"+num2str(runNum)
2446        else
2447                if(runNum<100)
2448                        numStr = "0"+num2str(runNum)
2449                else
2450                        numStr = num2str(runNum)
2451                Endif
2452        Endif
2453        //date()[0] is the first letter of the day of the week
2454        // OK for most cases, except for an overnight simulation! then the suffix won't sort right...
2455//      tw[0] = prefix+numstr+".SA2_SIM_"+(date()[0])+numStr
2456
2457//fancier, JAN=A, FEB=B, etc...
2458        String timeStr= secs2date(datetime,-1)
2459        String monthStr=StringFromList(1, timeStr  ,"/")
2460
2461        tw[0] = prefix+numstr+".SA2_SIM_"+(num2char(str2num(monthStr)+64))+numStr
2462       
2463        labelStr = PadString(labelStr,60,0x20)  //60 fortran-style spaces
2464        tw[6] = labelStr[0,59]
2465       
2466        return(0)
2467End
2468
2469Function ExamineHeader(type)
2470        String type
2471
2472        String data_folder = type
2473        String dataPath = "root:Packages:NIST:"+data_folder
2474        String cur_folder = "ExamineHeader"
2475        String curPath = "root:Packages:NIST:"+cur_folder
2476       
2477        //SetDataFolder curPath
2478
2479        Wave intw=$(dataPath+":IntegersRead")
2480        Wave realw=$(dataPath+":RealsRead")
2481        Wave/T textw=$(dataPath+":TextRead")
2482        Wave logw=$(dataPath+":LogicalsRead")
2483
2484
2485        print "----------------------------------"
2486        print "Header Details"
2487        print "----------------------------------"
2488        print "fname :\t\t"+textw[0]
2489        //
2490        print "run.npre :\t\t"+num2str(intw[0])
2491        print "run.ctime :\t\t"+num2str(intw[1])
2492        print "run.rtime :\t\t"+num2str(intw[2])
2493        print "run.numruns :\t\t"+num2str(intw[3])
2494        //
2495        print "run.moncnt :\t\t"+num2str(realw[0])
2496        print "run.savmon :\t\t"+num2str(realw[1])
2497        print "run.detcnt :\t\t"+num2str(realw[2])
2498        print "run.atten :\t\t"+num2str(realw[3])       
2499        //
2500        print "run.timdat:\t\t"+textw[1]
2501        print "run.type:\t\t"+textw[2]
2502        print "run.defdir:\t\t"+textw[3]
2503        print "run.mode:\t\t"+textw[4]
2504        print "run.reserve:\t\t"+textw[5]
2505        print "sample.labl:\t\t"+textw[6]
2506        //
2507        print "sample.trns:\t\t"+num2str(realw[4])
2508        print "sample.thk:\t\t"+num2str(realw[5])
2509        print "sample.position:\t\t"+num2str(realw[6])
2510        print "sample.rotang:\t\t"+num2str(realw[7])
2511        //
2512        print "sample.table:\t\t"+num2str(intw[4])
2513        print "sample.holder:\t\t"+num2str(intw[5])
2514        print "sample.blank:\t\t"+num2str(intw[6])
2515        //
2516        print "sample.temp:\t\t"+num2str(realw[8])
2517        print "sample.field:\t\t"+num2str(realw[9])     
2518        //
2519        print "sample.tctrlr:\t\t"+num2str(intw[7])
2520        print "sample.magnet:\t\t"+num2str(intw[8])
2521        //
2522        print "sample.tunits:\t\t"+textw[7]
2523        print "sample.funits:\t\t"+textw[8]
2524        print "det.typ:\t\t"+textw[9]
2525        //
2526        print "det.calx(1):\t\t"+num2str(realw[10])
2527        print "det.calx(2):\t\t"+num2str(realw[11])
2528        print "det.calx(3):\t\t"+num2str(realw[12])
2529        print "det.caly(1):\t\t"+num2str(realw[13])
2530        print "det.caly(2):\t\t"+num2str(realw[14])
2531        print "det.caly(3):\t\t"+num2str(realw[15])
2532        //
2533        print "det.num:\t\t"+num2str(intw[9])
2534        print "det.spacer:\t\t"+num2str(intw[10])
2535        //
2536        print "det.beamx:\t\t"+num2str(realw[16])
2537        print "det.beamy:\t\t"+num2str(realw[17])
2538        print "det.dis:\t\t"+num2str(realw[18])
2539        print "det.offset:\t\t"+num2str(realw[19])
2540        print "det.siz:\t\t"+num2str(realw[20])
2541        print "det.bstop:\t\t"+num2str(realw[21])
2542        print "det.blank:\t\t"+num2str(realw[22])
2543        print "resolution.ap1:\t\t"+num2str(realw[23])
2544        print "resolution.ap2:\t\t"+num2str(realw[24])
2545        print "resolution.ap12dis:\t\t"+num2str(realw[25])
2546        print "resolution.lmda:\t\t"+num2str(realw[26])
2547        print "resolution.dlmda:\t\t"+num2str(realw[27])
2548        print "resolution.nlenses:\t\t"+num2str(realw[28])     
2549        //
2550        print "tslice.slicing:\t\t"+num2str(logw[0])
2551        //
2552        print "tslice.multfact:\t\t"+num2str(intw[11])
2553        print "tslice.ltslice:\t\t"+num2str(intw[12])
2554        //
2555        print "temp.printemp:\t\t"+num2str(logw[1])
2556        //
2557        print "temp.hold:\t\t"+num2str(realw[29])
2558        print "temp.err:\t\t"+num2str(realw[30])
2559        print "temp.blank:\t\t"+num2str(realw[31])
2560        //
2561        print "temp.extra:\t\t"+num2str(intw[13])
2562        print "temp.err:\t\t"+num2str(intw[14])
2563        //
2564        print "magnet.printmag:\t\t"+num2str(logw[2])
2565        print "magnet.sensor:\t\t"+num2str(logw[3])
2566        //
2567        print "magnet.current:\t\t"+num2str(realw[32])
2568        print "magnet.conv:\t\t"+num2str(realw[33])
2569        print "magnet.fieldlast:\t\t"+num2str(realw[34])
2570        print "magnet.blank:\t\t"+num2str(realw[35])
2571        print "magnet.spacer:\t\t"+num2str(realw[36])
2572        print "bmstp.xpos:\t\t"+num2str(realw[37])
2573        print "bmstop.ypos:\t\t"+num2str(realw[38])
2574        //     
2575        print "params.blank1:\t\t"+num2str(intw[15])
2576        print "params.blank2:\t\t"+num2str(intw[16])
2577        print "params.blank3:\t\t"+num2str(intw[17])
2578        //
2579        print "params.trnscnt:\t\t"+num2str(realw[39])
2580        print "params.extra1:\t\t"+num2str(realw[40])
2581        print "params.extra2:\t\t"+num2str(realw[41])
2582        print "params.extra3:\t\t"+num2str(realw[42])
2583        //     
2584        print "params.reserve:\t\t"+textw[10]
2585        //
2586        print "voltage.printemp:\t\t"+num2str(logw[4])
2587        //
2588        print "voltage.volts:\t\t"+num2str(realw[43])
2589        print "voltage.blank:\t\t"+num2str(realw[44])
2590        //     
2591        print "voltage.spacer:\t\t"+num2str(intw[18])
2592        //
2593        print "polarization.printpol:\t\t"+num2str(logw[5])
2594        print "polarization.flipper:\t\t"+num2str(logw[6])
2595        //     
2596        print "polarization.horiz:\t\t"+num2str(realw[45])
2597        print "polarization.vert:\t\t"+num2str(realw[46])
2598        //
2599        print "analysis.rows(1):\t\t"+num2str(intw[19])
2600        print "analysis.rows(2):\t\t"+num2str(intw[20])
2601        print "analysis.cols(1):\t\t"+num2str(intw[21])
2602        print "analysis.cols(2):\t\t"+num2str(intw[22])
2603        //
2604        print "analysis.factor:\t\t"+num2str(realw[47])
2605        print "analysis.qmin:\t\t"+num2str(realw[48])
2606        print "analysis.qmax:\t\t"+num2str(realw[49])
2607        print "analysis.imin:\t\t"+num2str(realw[50])
2608        print "analysis.imax:\t\t"+num2str(realw[51])
2609
2610End
2611
2612
2613// Sept 2009 -SRK
2614// the ICE instrument control software is not correctly writing out the file name to the header in the specific
2615// case of a file prefix less than 5 characters. ICE is quite naturally putting the blanke space(s) at the end of
2616// the string. However, the VAX puts them at the beginning...
2617Proc PatchFileNameInHeader(firstFile,lastFile)
2618        Variable firstFile=1,lastFile=100
2619
2620        fPatchFileName(firstFile,lastFile)
2621
2622End
2623
2624Proc ReadFileNameInHeader(firstFile,lastFile)
2625        Variable firstFile=1,lastFile=100
2626       
2627        fReadFileName(firstFile,lastFile)
2628End
2629
2630
2631// simple utility to patch the file name in the file headers
2632// lo is the first file number
2633// hi is the last file number (inclusive)
2634//
2635// will read the 21 character file name and put any spaces at the front of the string
2636// like the VAX does. Should have absolutely no effect if there are spaces at the
2637// beginning of the string, as the VAX does.
2638Function fPatchFileName(lo,hi)
2639        Variable lo,hi
2640       
2641        Variable ii
2642        String file,fileName
2643       
2644        //loop over all files
2645        for(ii=lo;ii<=hi;ii+=1)
2646                file = FindFileFromRunNumber(ii)
2647                if(strlen(file) != 0)
2648                        fileName = getFileName(file)
2649                        WriteFileNameToHeader(file,fileName)
2650                else
2651                        printf "run number %d not found\r",ii
2652                endif
2653        endfor
2654       
2655        return(0)
2656End
2657
2658// simple utility to read the file name stored in the file header (and the suffix)
2659Function fReadFileName(lo,hi)
2660        Variable lo,hi
2661       
2662        String file,fileName,suffix
2663        Variable ii
2664       
2665        for(ii=lo;ii<=hi;ii+=1)
2666                file = FindFileFromRunNumber(ii)
2667                if(strlen(file) != 0)
2668                        fileName = getFileName(file)
2669                        suffix = getSuffix(file)
2670                        printf "File %d:  File name = %s\t\tSuffix = %s\r",ii,fileName,suffix
2671                else
2672                        printf "run number %d not found\r",ii
2673                endif
2674        endfor
2675       
2676        return(0)
2677End
2678
2679
2680
2681
2682// April 2009 - AJJ
2683// The new ICE instrument control software was not correctly writing the run.defdir field
2684// The format of that field should be [NGxSANSn] where x is 3 or 7 and nn is 0 through 50
2685
2686Proc PatchUserAccountName(firstFile,lastFile,acctName)
2687        Variable firstFile=1,lastFile=100
2688        String acctName = "NG3SANS0"
2689
2690        fPatchUserAccountName(firstFile,lastFile,acctName)
2691
2692End
2693
2694Proc ReadUserAccountName(firstFile,lastFile)
2695        Variable firstFile=1,lastFile=100
2696       
2697        fReadUserAccountName(firstFile,lastFile)
2698End
2699
2700// simple utility to patch the user account name in the file headers
2701// pass in the account name as a string
2702// lo is the first file number
2703// hi is the last file number (inclusive)
2704//
2705Function fPatchUserAccountName(lo,hi,acctName)
2706        Variable lo,hi
2707        String acctName
2708       
2709        Variable ii
2710        String file
2711       
2712        //loop over all files
2713        for(ii=lo;ii<=hi;ii+=1)
2714                file = FindFileFromRunNumber(ii)
2715                if(strlen(file) != 0)
2716                        WriteAcctNameToHeader(file,acctName)
2717                else
2718                        printf "run number %d not found\r",ii
2719                endif
2720        endfor
2721       
2722        return(0)
2723End
2724
2725// simple utility to read the user account name stored in the file header
2726Function fReadUserAccountName(lo,hi)
2727        Variable lo,hi
2728       
2729        String file,acctName
2730        Variable ii
2731       
2732        for(ii=lo;ii<=hi;ii+=1)
2733                file = FindFileFromRunNumber(ii)
2734                if(strlen(file) != 0)
2735                        acctName = getAcctName(file)
2736                        printf "File %d:  Account name = %s\r",ii,acctName
2737                else
2738                        printf "run number %d not found\r",ii
2739                endif
2740        endfor
2741       
2742        return(0)
2743End
2744
2745// May 2009 - SRK
2746// Monitor count not written correctly to file from ICE
2747
2748Proc PatchMonitorCount(firstFile,lastFile,monCtRate)
2749        Variable firstFile=1,lastFile=100,monCtRate
2750
2751        fPatchMonitorCount(firstFile,lastFile,monCtRate)
2752
2753End
2754
2755Proc ReadMonitorCount(firstFile,lastFile)
2756        Variable firstFile=1,lastFile=100
2757       
2758        fReadMonitorCount(firstFile,lastFile)
2759End
2760
2761// simple utility to patch the user account name in the file headers
2762// pass in the account name as a string
2763// lo is the first file number
2764// hi is the last file number (inclusive)
2765//
2766Function fPatchMonitorCount(lo,hi,monCtRate)
2767        Variable lo,hi,monCtRate
2768       
2769        Variable ii,ctTime
2770        String file
2771       
2772        //loop over all files
2773        for(ii=lo;ii<=hi;ii+=1)
2774                file = FindFileFromRunNumber(ii)
2775                if(strlen(file) != 0)
2776                        ctTime = getCountTime(file)
2777                        WriteMonitorCountToHeader(file,ctTime*monCtRate)                       
2778                else
2779                        printf "run number %d not found\r",ii
2780                endif
2781        endfor
2782       
2783        return(0)
2784End
2785
2786// simple utility to read the user account name stored in the file header
2787Function fReadMonitorCount(lo,hi)
2788        Variable lo,hi
2789       
2790        String file
2791        Variable ii,monitorCount
2792       
2793        for(ii=lo;ii<=hi;ii+=1)
2794                file = FindFileFromRunNumber(ii)
2795                if(strlen(file) != 0)
2796                        monitorCount = getMonitorCount(file)
2797                        printf "File %d:  Monitor Count = %g\r",ii,monitorCount
2798                else
2799                        printf "run number %d not found\r",ii
2800                endif
2801        endfor
2802       
2803        return(0)
2804End
2805
2806
2807/////
2808Proc ReadDetectorCount(firstFile,lastFile)
2809        Variable firstFile=1,lastFile=100
2810       
2811        fReadDetectorCount(firstFile,lastFile)
2812End
2813
2814
2815// simple utility to read the detector count from the header, and the summed data value
2816// and print out the values
2817Function fReadDetectorCount(lo,hi)
2818        Variable lo,hi
2819       
2820        String file
2821        Variable ii,summed
2822       
2823        for(ii=lo;ii<=hi;ii+=1)
2824                file = FindFileFromRunNumber(ii)
2825                if(strlen(file) != 0)
2826                        ReadHeaderAndData(file)
2827                        Wave rw=root:Packages:NIST:RAW:RealsRead
2828                        Wave data=root:Packages:NIST:RAW:data                   //data as read in is linear
2829                        summed = sum(data,-inf,inf)
2830                        printf "File %d:  DetCt Header = %g\t Detector Sum = %g\t Ratio sum/hdr = %g\r",ii,rw[2],summed,summed/rw[2]
2831                else
2832                        printf "run number %d not found\r",ii
2833                endif
2834        endfor
2835       
2836        return(0)
2837End
2838
2839
2840////// OCT 2009, facility specific bits from ProDiv()
2841//"type" is the data folder that has the corrected, patched, and normalized DIV data array
2842//
2843// the header of this file is rather unimportant. Filling in a title at least would be helpful/
2844//
2845Function Write_DIV_File(type)
2846        String type
2847       
2848        // Your file writing function here. Don't try to duplicate the VAX binary format...
2849        WriteVAXWorkFile(type)
2850       
2851        return(0)
2852End
2853
2854//writes an VAX-style WORK file, "exactly" as it would be output from the VAX
2855//except for the "dummy" header and the record markers - the record marker bytes are
2856// in the files - they are just written as zeros and are meaningless
2857//file is:
2858//      516 bytes header
2859// 128x128=16384 (x4) bytes of data
2860// + 2 byte record markers interspersed just for fun
2861// = 66116 bytes
2862//prompts for name of the output file.
2863//
2864Function WriteVAXWorkFile(type)
2865        String type
2866       
2867        Wave data=$("root:Packages:NIST:"+type+":data")
2868       
2869        Variable refnum,ii=0,hdrBytes=516,a,b,offset
2870        String fullpath=""
2871       
2872        Duplicate/O data,tempData
2873        Redimension/S/N=(128*128) tempData
2874        tempData *= 4
2875       
2876        PathInfo/S catPathName
2877        fullPath = DoSaveFileDialog("Save data as")       //won't actually open the file
2878        If(cmpstr(fullPath,"")==0)
2879                //user cancel, don't write out a file
2880          Close/A
2881          Abort "no data file was written"
2882        Endif
2883       
2884        Make/B/O/N=(hdrBytes) hdrWave
2885        hdrWave=0
2886        FakeDIVHeader(hdrWave)
2887       
2888        Make/Y=2/O/N=(510) bw510                //Y=2 specifies 32 bit (=4 byte) floating point
2889        Make/Y=2/O/N=(511) bw511
2890        Make/Y=2/O/N=(48) bw48
2891
2892        Make/O/B/N=2 recWave            //two bytes
2893
2894        //actually open the file
2895        Open/C="????"/T="TEXT" refNum as fullpath
2896        FSetPos refNum, 0
2897        //write header bytes (to be skipped when reading the file later)
2898       
2899        FBinWrite /F=1 refnum,hdrWave
2900       
2901        ii=0
2902        a=0
2903        do
2904                //write 511 4-byte values (little-endian order), 4* true value
2905                bw511[] = tempData[p+a]
2906                FBinWrite /B=3/F=4 refnum,bw511
2907                a+=511
2908                //write a 2-byte record marker
2909                FBinWrite refnum,recWave
2910               
2911                //write 510 4-byte values (little-endian) 4* true value
2912                bw510[] = tempData[p+a]
2913                FBinWrite /B=3/F=4 refnum,bw510
2914                a+=510
2915               
2916                //write a 2-byte record marker
2917                FBinWrite refnum,recWave
2918               
2919                ii+=1   
2920        while(ii<16)
2921        //write out last 48  4-byte values (little-endian) 4* true value
2922        bw48[] = tempData[p+a]
2923        FBinWrite /B=3/F=4 refnum,bw48
2924        //close the file
2925        Close refnum
2926       
2927        //go back through and make it look like a VAX datafile
2928        Make/W/U/O/N=(511*2) int511             // /W=16 bit signed integers /U=unsigned
2929        Make/W/U/O/N=(510*2) int510
2930        Make/W/U/O/N=(48*2) int48
2931       
2932        //skip the header for now
2933        Open/A/T="????TEXT" refnum as fullPath
2934        FSetPos refnum,0
2935       
2936        offset=hdrBytes
2937        ii=0
2938        do
2939                //511*2 integers
2940                FSetPos refnum,offset
2941                FBinRead/B=2/F=2 refnum,int511
2942                Swap16BWave(int511)
2943                FSetPos refnum,offset
2944                FBinWrite/B=2/F=2 refnum,int511
2945               
2946                //skip 511 4-byte FP = (511*2)*2 2byte int  + 2 bytes record marker
2947                offset += 511*2*2 + 2
2948               
2949                //510*2 integers
2950                FSetPos refnum,offset
2951                FBinRead/B=2/F=2 refnum,int510
2952                Swap16BWave(int510)
2953                FSetPos refnum,offset
2954                FBinWrite/B=2/F=2 refnum,int510
2955               
2956                //
2957                offset += 510*2*2 + 2
2958               
2959                ii+=1
2960        while(ii<16)
2961        //48*2 integers
2962        FSetPos refnum,offset
2963        FBinRead/B=2/F=2 refnum,int48
2964        Swap16BWave(int48)
2965        FSetPos refnum,offset
2966        FBinWrite/B=2/F=2 refnum,int48
2967
2968        //move to EOF and close
2969        FStatus refnum
2970        FSetPos refnum,V_logEOF
2971       
2972        Close refnum
2973       
2974        Killwaves/Z hdrWave,bw48,bw511,bw510,recWave,temp16,int511,int510,int48
2975End
2976
2977// given a 16 bit integer wave, read in as 2-byte pairs of 32-bit FP data
2978// swap the order of the 2-byte pairs
2979//
2980Function Swap16BWave(w)
2981        Wave w
2982
2983        Duplicate/O w,temp16
2984        //Variable num=numpnts(w),ii=0
2985
2986        //elegant way to swap even/odd values, using wave assignments
2987        w[0,*;2] = temp16[p+1]
2988        w[1,*;2] = temp16[p-1]
2989
2990//crude way, using a loop       
2991//      for(ii=0;ii<num;ii+=2)
2992//              w[ii] = temp16[ii+1]
2993//              w[ii+1] = temp16[ii]
2994//      endfor
2995       
2996        return(0)       
2997End
2998
2999// writes a fake label into the header of the DIV file
3000//
3001Function FakeDIVHeader(hdrWave)
3002        WAVE hdrWave
3003       
3004        //put some fake text into the sample label position (60 characters=60 bytes)
3005        String day=date(),tim=time(),lbl=""
3006        Variable start=98,num,ii
3007       
3008        lbl = "Sensitivity (DIV) created "+day +" "+tim
3009        num=strlen(lbl)
3010        for(ii=0;ii<num;ii+=1)
3011                hdrWave[start+ii] = char2num(lbl[ii])
3012        endfor
3013
3014        return(0)
3015End
3016
3017////////end of ProDiv() specifics
Note: See TracBrowser for help on using the repository browser.