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

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

Adding functions to patch broken run.defdir field required for correct attenuation determination.

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