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

Last change on this file since 757 was 757, checked in by srkline, 12 years ago

Fixed bug re-introduced by using the global ASCII code for Angstrom. Now it will use a default "A" if the global does not exist, rather than throwin up an error.

For 2D MC simulation, now if the data was scaled to ABS, the 2D data is "un-scaled" back to raw counts before saving as VAX format. A few counts may be lost here and there during the conversion, but less than 0.01% in my limited testing.

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