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

Last change on this file since 496 was 496, checked in by srkline, 14 years ago

Two changes:
(1) Changed the behavior of DIV file creation. Now a panel is presented that asks for all of the information - run numbers, transmission, XY box, etc. and then does all of the reduction/replacing/saving with one click. Cedric's ticket #195

(2) Some fixes in USANS notebook generation - filtering out junk.

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