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

Last change on this file since 890 was 886, checked in by srkline, 10 years ago

Changes to SASCALC and other locations in the code that identify the instrument from the account name that is stored in the file header. New designation of NGA for the 10-m SANS, and NGB is reserved for the NG3 30-m SANS when it is moved into the new guide hall. Changes to incorporate the 10m SANS are functional, but INCOMPLETE since many of the instrument details have not been filled in yet (they haven't been measured yet).

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