source: sans/SANSReduction/branches/kline_29MAR07/Put in User Procedures/SANS_Reduction_v5.00/NCNR_DataReadWrite.ipf @ 72

Last change on this file since 72 was 72, checked in by srkline, 16 years ago

more transferring of functions to NCNR_* files.

File size: 34.3 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion = 5.0
4
5//**************************
6//
7// Vers. 1.2 092101
8// Vers. 5.0 29MAR07 - branched from main reduction to split out facility
9//                     specific calls
10//
11// functions for reading raw data files from the VAX
12// - RAW data files are read into the RAW folder - integer data from the detector
13//   is decompressed and given the proper orientation
14// - header information is placed into real,integer, or text waves in the order they appear
15//   in the file header
16//
17// Work data (DIV File) is read into the DIV folder
18//
19//*****************************
20
21//simple, main entry procedure that will load a RAW sans data file (not a work file)
22//into the RAW dataFolder
23//(typically called from main panel button)
24//
25Proc LoadSANSData()
26        String msgStr = "Select a SANS data file"
27       
28        Variable err
29        err = ReadBinarySANS(msgStr)            //will prompt for file
30        //ignore the error here
31End
32
33
34//function called by the main entry procedure
35//sets global display variable, reads in the data, and displays it
36//displays alert, and returns error if no file was selected
37//
38// calling routine must decide whether to abort the execution or not...
39Function ReadBinarySANS(msgStr)
40        String msgStr
41
42        String filename=""
43
44        //each routine is responsible for checking the current (displayed) data folder
45        //selecting it, and returning to root when done
46        PathInfo/S catPathName          //should set the next dialog to the proper path...
47        //get the filename, then read it in
48        filename = PromptForPath(msgStr)
49        //check for cancel from dialog
50        if(strlen(filename)==0)
51                //user cancelled, abort
52                SetDataFolder root:
53                DoAlert 0, "No file selected, action aborted"
54                return(1)
55        Endif
56        //Print  "GetFileNameFromPath(filename) = " +  GetFileNameFromPathNoSemi(filename)
57        ReadHeaderAndData(filename)     //this is the full Path+file
58
59        //the calling macro must change the display type
60        String/G root:myGlobals:gDataDisplayType="RAW"          //displayed data type is raw
61       
62        //data is displayed here
63        fRawWindowHook()
64       
65        Return(0)
66End
67
68//function that does the guts of reading the binary data file
69//fname is the full path:name;vers required to open the file
70//VAX record markers are skipped as needed
71//the data as read in is in compressed I*2 format, and is decompressed
72//immediately after being read in. The final root:RAW:data wave is the real
73//neutron counts and can be directly operated on
74//header information is put into three wave, integers,reals, and text
75//logicals in the header are currently skipped, since they are no use in the
76//data reduction process. the logicals, however are left untouched.
77//
78Function ReadHeaderAndData(fname)
79        String fname
80        //this function is for reading in RAW data only, so it will always put data in RAW folder
81        String curPath = "root:RAW"
82        SetDataFolder curPath           //use the full path, so it will always work
83        Variable/G root:RAW:gIsLogScale = 0             //initial state is linear, keep this in RAW folder
84       
85        Variable refNum,integer,realval
86        String sansfname,textstr
87       
88        Make/O/N=23 $"root:RAW:IntegersRead"
89        Make/O/N=52 $"root:RAW:RealsRead"
90        Make/O/T/N=11 $"root:RAW:TextRead"
91       
92        Wave intw=$"root:RAW:IntegersRead"
93        Wave realw=$"root:RAW:RealsRead"
94        Wave/T textw=$"root:RAW:TextRead"
95       
96        //***NOTE ****
97        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
98        // this read routine, after the open dialog is presented
99        // the "--read" waves end up in the correct folder, but the data does not! Why?
100        //must re-set data folder before writing data array (done below)
101       
102        //full filename and path is now passed in...
103        //actually open the file
104        Open/R refNum as fname
105        //skip first two bytes (VAX record length markers, not needed here)
106        FSetPos refNum, 2
107        //read the next 21 bytes as characters (fname)
108        FReadLine/N=21 refNum,textstr
109        textw[0]= textstr
110        //read four i*4 values  /F=3 flag, B=3 flag
111        FBinRead/F=3/B=3 refNum, integer
112        intw[0] = integer
113        //
114        FBinRead/F=3/B=3 refNum, integer
115        intw[1] = integer
116        //
117        FBinRead/F=3/B=3 refNum, integer
118        intw[2] = integer
119        //
120        FBinRead/F=3/B=3 refNum, integer
121        intw[3] = integer
122        // 6 text fields
123        FSetPos refNum,55               //will start reading at byte 56
124        FReadLine/N=20 refNum,textstr
125        textw[1]= textstr
126        FReadLine/N=3 refNum,textstr
127        textw[2]= textstr
128        FReadLine/N=11 refNum,textstr
129        textw[3]= textstr
130        FReadLine/N=1 refNum,textstr
131        textw[4]= textstr
132        FReadLine/N=8 refNum,textstr
133        textw[5]= textstr
134        FReadLine/N=60 refNum,textstr
135        textw[6]= textstr
136       
137        //3 integers
138        FSetPos refNum,174
139        FBinRead/F=3/B=3 refNum, integer
140        intw[4] = integer
141        FBinRead/F=3/B=3 refNum, integer
142        intw[5] = integer
143        FBinRead/F=3/B=3 refNum, integer
144        intw[6] = integer
145       
146        //2 integers, 3 text fields
147        FSetPos refNum,194
148        FBinRead/F=3/B=3 refNum, integer
149        intw[7] = integer
150        FBinRead/F=3/B=3 refNum, integer
151        intw[8] = integer
152        FReadLine/N=6 refNum,textstr
153        textw[7]= textstr
154        FReadLine/N=6 refNum,textstr
155        textw[8]= textstr
156        FReadLine/N=6 refNum,textstr
157        textw[9]= textstr
158       
159        //2 integers
160        FSetPos refNum,244
161        FBinRead/F=3/B=3 refNum, integer
162        intw[9] = integer
163        FBinRead/F=3/B=3 refNum, integer
164        intw[10] = integer
165       
166        //2 integers
167        FSetPos refNum,308
168        FBinRead/F=3/B=3 refNum, integer
169        intw[11] = integer
170        FBinRead/F=3/B=3 refNum, integer
171        intw[12] = integer
172       
173        //2 integers
174        FSetPos refNum,332
175        FBinRead/F=3/B=3 refNum, integer
176        intw[13] = integer
177        FBinRead/F=3/B=3 refNum, integer
178        intw[14] = integer
179       
180        //3 integers
181        FSetPos refNum,376
182        FBinRead/F=3/B=3 refNum, integer
183        intw[15] = integer
184        FBinRead/F=3/B=3 refNum, integer
185        intw[16] = integer
186        FBinRead/F=3/B=3 refNum, integer
187        intw[17] = integer
188       
189        //1 text field
190        FSetPos refNum,404
191        FReadLine/N=42 refNum,textstr
192        textw[10]= textstr
193       
194        //1 integer
195        FSetPos refNum,458
196        FBinRead/F=3/B=3 refNum, integer
197        intw[18] = integer
198       
199        //4 integers
200        FSetPos refNum,478
201        FBinRead/F=3/B=3 refNum, integer
202        intw[19] = integer
203        FBinRead/F=3/B=3 refNum, integer
204        intw[20] = integer
205        FBinRead/F=3/B=3 refNum, integer
206        intw[21] = integer
207        FBinRead/F=3/B=3 refNum, integer
208        intw[22] = integer
209       
210        Close refNum
211       
212        //now get all of the reals
213        //
214        //Do all the GBLoadWaves at the end
215        //
216        //FBinRead Cannot handle 32 bit VAX floating point
217        //GBLoadWave, however, can properly read it
218        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
219        String strToExecute
220        //append "/S=offset/U=numofreals" to control the read
221        // then append fname to give the full file path
222        // then execute
223       
224        Variable a=0,b=0
225       
226        SetDataFolder curPath
227       
228        // 4 R*4 values
229        strToExecute = GBLoadStr + "/S=39/U=4" + "\"" + fname + "\""
230        Execute strToExecute
231        Wave w=$"root:RAW:tempGBWave0"
232        b=4     //num of reals read
233        realw[a,a+b-1] = w[p-a]
234        a+=b
235       
236        // 4 R*4 values
237        SetDataFolder curPath
238        strToExecute = GBLoadStr + "/S=158/U=4" + "\"" + fname + "\""
239        Execute strToExecute
240        b=4     
241        realw[a,a+b-1] = w[p-a]
242        a+=b
243
244///////////
245        // 2 R*4 values
246        SetDataFolder curPath
247        strToExecute = GBLoadStr + "/S=186/U=2" + "\"" + fname + "\""
248        Execute strToExecute
249        b=2     
250        realw[a,a+b-1] = w[p-a]
251        a+=b
252
253        // 6 R*4 values
254        SetDataFolder curPath
255        strToExecute = GBLoadStr + "/S=220/U=6" + "\"" + fname + "\""
256        Execute strToExecute
257        b=6     
258        realw[a,a+b-1] = w[p-a]
259        a+=b
260       
261        // 13 R*4 values
262        SetDataFolder curPath
263        strToExecute = GBLoadStr + "/S=252/U=13" + "\"" + fname + "\""
264        Execute strToExecute
265        b=13
266        realw[a,a+b-1] = w[p-a]
267        a+=b
268       
269        // 3 R*4 values
270        SetDataFolder curPath
271        strToExecute = GBLoadStr + "/S=320/U=3" + "\"" + fname + "\""
272        Execute strToExecute
273        b=3     
274        realw[a,a+b-1] = w[p-a]
275        a+=b
276       
277        // 7 R*4 values
278        SetDataFolder curPath
279        strToExecute = GBLoadStr + "/S=348/U=7" + "\"" + fname + "\""
280        Execute strToExecute
281        b=7
282        realw[a,a+b-1] = w[p-a]
283        a+=b
284       
285        // 4 R*4 values
286        SetDataFolder curPath
287        strToExecute = GBLoadStr + "/S=388/U=4" + "\"" + fname + "\""
288        Execute strToExecute
289        b=4     
290        realw[a,a+b-1] = w[p-a]
291        a+=b
292       
293        // 2 R*4 values
294        SetDataFolder curPath
295        strToExecute = GBLoadStr + "/S=450/U=2" + "\"" + fname + "\""
296        Execute strToExecute
297        b=2
298        realw[a,a+b-1] = w[p-a]
299        a+=b
300       
301        // 2 R*4 values
302        SetDataFolder curPath
303        strToExecute = GBLoadStr + "/S=470/U=2" + "\"" + fname + "\""
304        Execute strToExecute
305        b=2
306        realw[a,a+b-1] = w[p-a]
307        a+=b
308       
309        // 5 R*4 values
310        SetDataFolder curPath
311        strToExecute = GBLoadStr + "/S=494/U=5" + "\"" + fname + "\""
312        Execute strToExecute
313        b=5     
314        realw[a,a+b-1] = w[p-a]
315       
316        //if the binary VAX data ws transferred to a MAC, all is OK
317        //if the data was trasnferred to an Intel machine (IBM), all the real values must be
318        //divided by 4 to get the correct floating point values
319        // I can't find any combination of settings in GBLoadWave or FBinRead to read data in correctly
320        // on an Intel machine.
321        //With the corrected version of GBLoadWave XOP (v. 1.43 or higher) Mac and PC both read
322        //VAX reals correctly, and no checking is necessary 12 APR 99
323        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
324                //do nothing
325        //else
326                //either Windows or Windows NT
327                //realw /= 4
328        //endif
329       
330        SetDataFolder curPath
331        //read in the data
332        strToExecute = "GBLoadWave/O/N=tempGBwave/B/T={16,2}/S=514/Q" + "\"" + fname + "\""
333        Execute strToExecute
334
335        SetDataFolder curPath           //use the full path, so it will always work
336       
337        Make/O/N=16384 $"root:RAW:data"
338        WAVE data=$"root:RAW:data"
339        SkipAndDecompressVAX(w,data)
340        Redimension/N=(128,128) data                    //NIST raw data is 128x128 - do not generalize
341       
342        //keep a string with the filename in the RAW folder
343        String/G root:RAW:fileList = textw[0]
344       
345        //set the globals to the detector dimensions (pixels)
346        Variable/G root:myGlobals:gNPixelsX=128         //default for Ordela data (also set in Initialize.ipf)
347        Variable/G root:myGlobals:gNPixelsY=128
348//      if(cmpstr(textW[9],"ILL   ")==0)                //override if OLD Cerca data
349//              Variable/G root:myGlobals:gNPixelsX=64
350//              Variable/G root:myGlobals:gNPixelsY=64
351//      endif
352       
353        //clean up - get rid of w = $"root:RAW:tempGBWave0"
354        KillWaves/Z w
355       
356        //return the data folder to root
357        SetDataFolder root:
358       
359        Return 0
360
361End
362
363
364//function to take the I*2 data that was read in, in VAX format
365//where the integers are "normal", but there are 2-byte record markers
366//sprinkled evenly through the data
367//there are skipped, leaving 128x128=16384 data values
368//the input array (in) is larger than 16384
369//(out) is 128x128 data (single precision) as defined in ReadHeaderAndData()
370//
371Function SkipAndDecompressVAX(in,out)
372        Wave in,out
373       
374        Variable skip,ii
375
376        ii=0
377        skip=0
378        do
379                if(mod(ii+skip,1022)==0)
380                        skip+=1
381                endif
382                out[ii] = Decompress(in[ii+skip])
383                ii+=1
384        while(ii<16384)
385        return(0)
386End
387
388//decompresses each I*2 data value to its real I*4 value
389//using the decompression routine written by Jim Ryhne, many moons ago
390//
391// the compression routine (not shown here, contained in the VAX fortran RW_DATAFILE.FOR) maps I4 to I2 values.
392// (back in the days where disk space *really* mattered). the I4toI2 function spit out:
393// I4toI2 = I4                                                          when I4 in [0,32767]
394// I4toI2 = -777                                                        when I4 in [2,767,000,...]
395// I4toI2 mapped to -13277 to -32768    otherwise
396//
397// the mapped values [-776,-1] and [-13276,-778] are not used.
398// in this compression scheme, only 4 significant digits are retained (to allow room for the exponent)
399// technically, the maximum value should be 2,768,499 since this maps to -32768. But this is of
400// little consequence. If you have individual pixel values on the detector that are that large, you need
401// to re-think your experiment.
402Function Decompress(val)
403        Variable val
404
405        Variable i4,npw,ipw,ib,nd
406
407        ib=10
408        nd=4
409        ipw=ib^nd
410        i4=val
411
412        if (i4 <= -ipw)
413                npw=trunc(-i4/ipw)
414                i4=mod(-i4,ipw)*(ib^npw)
415                return i4
416        else
417                return i4
418        endif
419End
420
421//****************
422//main entry procedure for reading a "WORK.DIV" file
423//displays a quick image of the  file, to check that it's correct
424//data is deposited in root:DIV data folder
425//
426Proc ReadWork_DIV()
427//      Silent 1
428       
429        String fname = PromptForPath("Select detector sensitivity file")
430        ReadHeaderAndWork("DIV",fname)          //puts what is read in work.div
431       
432        String waveStr = "root:DIV:data"
433        NewImage/F/K=1/S=2 $waveStr             //this is an experimental IGOR operation
434        ModifyImage '' ctab= {*,*,YellowHot,0}
435        //Display;AppendImage $waveStr
436       
437        //change the title string to WORK.DIV, rather than PLEXnnn_TST_asdfa garbage
438        String/G root:DIV:fileList = "WORK.DIV"
439       
440        SetDataFolder root:             //(redundant)
441//      Silent 0
442End
443
444
445//this function is the guts of reading a binary VAX file of real (4-byte) values
446// (i.e. a WORK.aaa file)
447// work files have the same header structure as RAW SANS data, just with
448//different data (real, rather than compressed integer data)
449//
450//************
451//this routine incorrectly reads in several data values where the VAX record
452//marker splits the 4-byte real (at alternating record markers)
453//this error seems to not be severe, but shoud be corrected (at great pain)
454//************
455//
456Function ReadHeaderAndWork(type,fname)
457        String type,fname
458       
459        //type is the desired folder to read the workfile to
460        //this data will NOT be automatically displayed gDataDisplayType is unchanged
461
462//      SVAR cur_folder=root:myGlobals:gDataDisplayType
463        String cur_folder = type
464        String curPath = "root:"+cur_folder
465        SetDataFolder curPath           //use the full path, so it will always work
466       
467        Variable refNum,integer,realval
468        String sansfname,textstr
469        Variable/G $(curPath + ":gIsLogScale") = 0              //initial state is linear, keep this in DIV folder
470       
471        Make/O/N=23 $(curPath + ":IntegersRead")
472        Make/O/N=52 $(curPath + ":RealsRead")
473        Make/O/T/N=11 $(curPath + ":TextRead")
474       
475        WAVE intw=$(curPath + ":IntegersRead")
476        WAVE realw=$(curPath + ":RealsRead")
477        WAVE/T textw=$(curPath + ":TextRead")
478       
479        //***NOTE ****
480        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
481        // this read routine, after the open dialog is presented
482        // the "--read" waves end up in the correct folder, but the data does not! Why?
483        //must re-set data folder before writing data array (done below)
484       
485        SetDataFolder curPath
486       
487        //actually open the file
488        Open/R refNum as fname
489        //skip first two bytes
490        FSetPos refNum, 2
491        //read the next 21 bytes as characters (fname)
492        FReadLine/N=21 refNum,textstr
493        textw[0]= textstr
494        //read four i*4 values  /F=3 flag, B=3 flag
495        FBinRead/F=3/B=3 refNum, integer
496        intw[0] = integer
497        //
498        FBinRead/F=3/B=3 refNum, integer
499        intw[1] = integer
500        //
501        FBinRead/F=3/B=3 refNum, integer
502        intw[2] = integer
503        //
504        FBinRead/F=3/B=3 refNum, integer
505        intw[3] = integer
506        // 6 text fields
507        FSetPos refNum,55               //will start reading at byte 56
508        FReadLine/N=20 refNum,textstr
509        textw[1]= textstr
510        FReadLine/N=3 refNum,textstr
511        textw[2]= textstr
512        FReadLine/N=11 refNum,textstr
513        textw[3]= textstr
514        FReadLine/N=1 refNum,textstr
515        textw[4]= textstr
516        FReadLine/N=8 refNum,textstr
517        textw[5]= textstr
518        FReadLine/N=60 refNum,textstr
519        textw[6]= textstr
520       
521        //3 integers
522        FSetPos refNum,174
523        FBinRead/F=3/B=3 refNum, integer
524        intw[4] = integer
525        FBinRead/F=3/B=3 refNum, integer
526        intw[5] = integer
527        FBinRead/F=3/B=3 refNum, integer
528        intw[6] = integer
529       
530        //2 integers, 3 text fields
531        FSetPos refNum,194
532        FBinRead/F=3/B=3 refNum, integer
533        intw[7] = integer
534        FBinRead/F=3/B=3 refNum, integer
535        intw[8] = integer
536        FReadLine/N=6 refNum,textstr
537        textw[7]= textstr
538        FReadLine/N=6 refNum,textstr
539        textw[8]= textstr
540        FReadLine/N=6 refNum,textstr
541        textw[9]= textstr
542       
543        //2 integers
544        FSetPos refNum,244
545        FBinRead/F=3/B=3 refNum, integer
546        intw[9] = integer
547        FBinRead/F=3/B=3 refNum, integer
548        intw[10] = integer
549       
550        //2 integers
551        FSetPos refNum,308
552        FBinRead/F=3/B=3 refNum, integer
553        intw[11] = integer
554        FBinRead/F=3/B=3 refNum, integer
555        intw[12] = integer
556       
557        //2 integers
558        FSetPos refNum,332
559        FBinRead/F=3/B=3 refNum, integer
560        intw[13] = integer
561        FBinRead/F=3/B=3 refNum, integer
562        intw[14] = integer
563       
564        //3 integers
565        FSetPos refNum,376
566        FBinRead/F=3/B=3 refNum, integer
567        intw[15] = integer
568        FBinRead/F=3/B=3 refNum, integer
569        intw[16] = integer
570        FBinRead/F=3/B=3 refNum, integer
571        intw[17] = integer
572       
573        //1 text field
574        FSetPos refNum,404
575        FReadLine/N=42 refNum,textstr
576        textw[10]= textstr
577       
578        //1 integer
579        FSetPos refNum,458
580        FBinRead/F=3/B=3 refNum, integer
581        intw[18] = integer
582       
583        //4 integers
584        FSetPos refNum,478
585        FBinRead/F=3/B=3 refNum, integer
586        intw[19] = integer
587        FBinRead/F=3/B=3 refNum, integer
588        intw[20] = integer
589        FBinRead/F=3/B=3 refNum, integer
590        intw[21] = integer
591        FBinRead/F=3/B=3 refNum, integer
592        intw[22] = integer
593       
594        Close refNum
595       
596        //now get all of the reals
597        //
598        //Do all the GBLoadWaves at the end
599        //
600        //FBinRead Cannot handle 32 bit VAX floating point
601        //GBLoadWave, however, can properly read it
602        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
603        String strToExecute
604        //append "/S=offset/U=numofreals" to control the read
605        // then append fname to give the full file path
606        // then execute
607       
608        Variable a=0,b=0
609       
610        SetDataFolder curPath
611        // 4 R*4 values
612        strToExecute = GBLoadStr + "/S=39/U=4" + "\"" + fname + "\""
613        Execute strToExecute
614       
615        SetDataFolder curPath
616        Wave w=$(curPath + ":tempGBWave0")
617        b=4     //num of reals read
618        realw[a,a+b-1] = w[p-a]
619        a+=b
620       
621        // 4 R*4 values
622        SetDataFolder curPath
623        strToExecute = GBLoadStr + "/S=158/U=4" + "\"" + fname + "\""
624        Execute strToExecute
625        b=4     
626        realw[a,a+b-1] = w[p-a]
627        a+=b
628
629///////////
630        // 2 R*4 values
631        SetDataFolder curPath
632        strToExecute = GBLoadStr + "/S=186/U=2" + "\"" + fname + "\""
633        Execute strToExecute
634        b=2     
635        realw[a,a+b-1] = w[p-a]
636        a+=b
637
638        // 6 R*4 values
639        SetDataFolder curPath
640        strToExecute = GBLoadStr + "/S=220/U=6" + "\"" + fname + "\""
641        Execute strToExecute
642        b=6     
643        realw[a,a+b-1] = w[p-a]
644        a+=b
645       
646        // 13 R*4 values
647        SetDataFolder curPath
648        strToExecute = GBLoadStr + "/S=252/U=13" + "\"" + fname + "\""
649        Execute strToExecute
650        b=13
651        realw[a,a+b-1] = w[p-a]
652        a+=b
653       
654        // 3 R*4 values
655        SetDataFolder curPath
656        strToExecute = GBLoadStr + "/S=320/U=3" + "\"" + fname + "\""
657        Execute strToExecute
658        b=3     
659        realw[a,a+b-1] = w[p-a]
660        a+=b
661       
662        // 7 R*4 values
663        SetDataFolder curPath
664        strToExecute = GBLoadStr + "/S=348/U=7" + "\"" + fname + "\""
665        Execute strToExecute
666        b=7
667        realw[a,a+b-1] = w[p-a]
668        a+=b
669       
670        // 4 R*4 values
671        SetDataFolder curPath
672        strToExecute = GBLoadStr + "/S=388/U=4" + "\"" + fname + "\""
673        Execute strToExecute
674        b=4     
675        realw[a,a+b-1] = w[p-a]
676        a+=b
677       
678        // 2 R*4 values
679        SetDataFolder curPath
680        strToExecute = GBLoadStr + "/S=450/U=2" + "\"" + fname + "\""
681        Execute strToExecute
682        b=2
683        realw[a,a+b-1] = w[p-a]
684        a+=b
685       
686        // 2 R*4 values
687        SetDataFolder curPath
688        strToExecute = GBLoadStr + "/S=470/U=2" + "\"" + fname + "\""
689        Execute strToExecute
690        b=2
691        realw[a,a+b-1] = w[p-a]
692        a+=b
693       
694        // 5 R*4 values
695        SetDataFolder curPath
696        strToExecute = GBLoadStr + "/S=494/U=5" + "\"" + fname + "\""
697        Execute strToExecute
698        b=5     
699        realw[a,a+b-1] = w[p-a]
700       
701        //if the binary VAX data ws transferred to a MAC, all is OK
702        //if the data was trasnferred to an Intel machine (IBM), all the real values must be
703        //divided by 4 to get the correct floating point values
704        // I can't find any combination of settings in GBLoadWave or FBinRead to read data in correctly
705        // on an Intel machine.
706        //With the corrected version of GBLoadWave XOP (v. 1.43 or higher) Mac and PC both read
707        //VAX reals correctly, and no checking is necessary 12 APR 99
708        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
709                //do nothing
710        //else
711                //either Windows or Windows NT
712                //realw /= 4
713        //endif
714       
715        //read in the data
716         GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
717
718        curPath = "root:"+cur_folder
719        SetDataFolder curPath           //use the full path, so it will always work
720       
721        Make/O/N=16384 $(curPath + ":data")
722        WAVE data = $(curPath + ":data")
723       
724        Variable skip,ii,offset
725       
726        //read in a total of 16384 values (ii)
727        //as follows :
728        // skip first 2 bytes
729        // skip 512 byte header
730        // skip first 2 bytes of data
731        //(read 511 reals, skip 2b, 510 reals, skip 2b) -16 times = 16336 values
732        // read the final 48 values in seperately to avoid EOF error
733       
734        /////////////
735        SetDataFolder curPath
736        skip = 0
737        ii=0
738        offset = 514 +2
739        a=0
740        do
741                SetDataFolder curPath
742               
743                strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=511" + "\"" + fname + "\""
744                Execute strToExecute
745                //Print strToExecute
746                b=511
747                data[a,a+b-1] = w[p-a]
748                a+=b
749               
750                offset += 511*4 +2
751               
752                strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=510" + "\"" + fname + "\""
753                SetDataFolder curPath
754                Execute strToExecute
755                //Print strToExecute
756                b=510
757                data[a,a+b-1] = w[p-a]
758                a+=b
759               
760                offset += 510*4 +2
761               
762                ii+=1
763                //Print "inside do, data[2] =",data[2]
764                //Print "inside do, tempGBwave0[0] = ",w[0]
765        while(ii<16)
766       
767        // 16336 values have been read in --
768        //read in last 64 values
769        strToExecute = GBLoadStr + "/S="+num2str(offset)+"/U=48" + "\"" + fname + "\""
770       
771        SetDataFolder curPath
772        Execute strToExecute
773        b=48
774        data[a,a+b-1] = w[p-a]
775        a+=b
776//
777/// done reading in raw data
778//
779        //Print "in workdatareader , data = ", data[1][1]
780
781        Redimension/n=(128,128) data
782       
783        //clean up - get rid of w = $"tempGBWave0"
784        KillWaves w
785       
786        //divide the FP data by 4 if read from a PC (not since GBLoadWave update)
787        //if(cmpstr("Macintosh",IgorInfo(2)) == 0)
788                //do nothing
789        //else
790                //either Windows or Windows NT
791                //data /= 4
792        //endif
793       
794        //keep a string with the filename in the DIV folder
795        String/G $(curPath + ":fileList") = textw[0]
796       
797        //return the data folder to root
798        SetDataFolder root:
799       
800        Return(0)
801End
802
803/////   ASC FORMAT READER  //////
804/////   FOR WORKFILE MATH PANEL //////
805
806//function to read in the ASC output of SANS reduction
807// currently the file has 20 header lines, followed by a single column
808// of 16384 values, Data is written by row, starting with Y=1 and X=(1->128)
809//
810//returns 0 if read was ok
811//returns 1 if there was an error
812//
813// assumes a square detector
814//
815Function ReadASCData(fname,destPath)
816        String fname, destPath
817        //this function is for reading in ASCII data so put data in user-specified folder
818        SetDataFolder "root:"+destPath
819
820        NVAR pixelsX = root:myGlobals:gNPixelsX
821        NVAR pixelsY = root:myGlobals:gNPixelsY
822        Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20
823        String str=""
824        //data is initially linear scale
825        Variable/G :gIsLogScale=0
826        Make/O/T/N=(numHdrLines) hdrLines
827        Make/O/D/N=(num*num) data//,linear_data
828       
829        //full filename and path is now passed in...
830        //actually open the file
831//      SetDataFolder destPath
832        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
833        if(refnum==0)           //FNF error, get out
834                DoAlert 0,"Could not find file: "+fname
835                Close/A
836                SetDataFolder root:
837                return(1)
838        endif
839        if(V_flag!=0)
840                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
841                Close/A
842                SetDataFolder root:
843                return(1)
844        Endif
845        //
846        for(ii=0;ii<numHdrLines;ii+=1)          //read (or skip) 18 header lines
847                FReadLine refnum,str
848                hdrLines[ii]=str
849        endfor
850        //     
851        Close refnum
852       
853//      SetDataFolder destPath
854        LoadWave/Q/G/D/N=temp fName
855        Wave/Z temp0=temp0
856        data=temp0
857        Redimension/N=(pixelsX,pixelsY) data//,linear_data
858       
859        //linear_data = data
860       
861        KillWaves/Z temp0
862       
863        //return the data folder to root
864        SetDataFolder root:
865       
866        Return(0)
867End
868
869// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
870// pay attention to what is/not to be trusted due to "fake" information
871//
872// destFolder is of the form "myGlobals:WorkMath:AAA"
873//
874Function FillFakeHeader_ASC(destFolder)
875        String destFolder
876        Make/O/N=23 $("root:"+destFolder+":IntegersRead")
877        Make/O/N=52 $("root:"+destFolder+":RealsRead")
878        Make/O/T/N=11 $("root:"+destFolder+":TextRead")
879       
880        Wave intw=$("root:"+destFolder+":IntegersRead")
881        Wave realw=$("root:"+destFolder+":RealsRead")
882        Wave/T textw=$("root:"+destFolder+":TextRead")
883       
884        //Put in appropriate "fake" values
885        //parse values as needed from headerLines
886        Wave/T hdr=$("root:"+destFolder+":hdrLines")
887        Variable monCt,lam,offset,sdd,trans,thick
888        Variable xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam
889        String detTyp=""
890        String tempStr="",formatStr="",junkStr=""
891        formatStr = "%g %g %g %g %g %g"
892        tempStr=hdr[3]
893        sscanf tempStr, formatStr, monCt,lam,offset,sdd,trans,thick
894//      Print monCt,lam,offset,sdd,trans,thick,avStr,step
895        formatStr = "%g %g %g %g %g %g %g %s"
896        tempStr=hdr[5]
897        sscanf tempStr,formatStr,xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
898//      Print xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
899       
900        realw[16]=xCtr          //xCtr(pixels)
901        realw[17]=yCtr  //yCtr (pixels)
902        realw[18]=sdd           //SDD (m)
903        realw[26]=lam           //wavelength (A)
904        //
905        // necessary values
906        realw[10]=5                     //detector calibration constants, needed for averaging
907        realw[11]=10000
908        realw[12]=0
909        realw[13]=5
910        realw[14]=10000
911        realw[15]=0
912        //
913        // used in the resolution calculation, ONLY here to keep the routine from crashing
914        realw[20]=65            //det size
915        realw[27]=dlam  //delta lambda
916        realw[21]=bsDiam        //BS size
917        realw[23]=a1            //A1
918        realw[24]=a2    //A2
919        realw[25]=a1a2Dist      //A1A2 distance
920        realw[4]=trans          //trans
921        realw[3]=0              //atten
922        realw[5]=thick          //thick
923        //
924        //
925        realw[0]=monCt          //def mon cts
926
927        // fake values to get valid deadtime and detector constants
928        //
929        textw[9]=detTyp+"  "            //6 characters 4+2 spaces
930        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
931       
932        //set the string values
933        formatStr="FILE: %s CREATED: %s"
934        sscanf hdr[0],formatStr,tempStr,junkStr
935//      Print tempStr
936//      Print junkStr
937        String/G $("root:"+destFolder+":fileList") = tempStr
938        textw[0] = tempStr              //filename
939        textw[1] = junkStr              //run date-time
940       
941        //file label = hdr[1]
942        tempStr = hdr[1]
943        tempStr = tempStr[0,strlen(tempStr)-2]          //clean off the last LF
944//      Print tempStr
945        textW[6] = tempStr      //sample label
946       
947        return(0)
948End
949
950
951
952
953
954
955////testing procedure that is not called anymore and is out-of-date
956////with the new data structures. update before re-implementing
957//Proc ReadBinaryWork()         //this procedure is not called anymore
958//
959////    Silent 1
960//     
961//      //make sure the globals are reset properly
962//      Variable/G root:myGlobals:gIsLogScale=0 //image is linearly scaled to begin with
963//      String/G root:myGlobals:gDataDisplayType="RAW"          //displayed data type is raw
964//     
965//      //each routine is responsible for checking the current (displayed) data folder
966//      //selecting it, and returning to root when done
967//     
968//      ReadHeaderAndWork()
969//
970//      SetDataFolder root:RAW
971//      //data is displayed here
972//      Display;AppendImage data
973//     
974////    Silent 0
975//     
976//      //data folder was changed from root in this macro
977//      SetDataFolder root:
978//End
979
980
981//
982
983
984
985/////*****************
986////unused testing procedure for writing a 4 byte floating point value in VAX format
987//Proc TestReWriteReal()
988//      String Path
989//      Variable value,start
990//     
991//      GetFileAndPath()
992//      Path = S_Path + S_filename
993//     
994//      value = 0.2222
995//      start = 158             //trans starts at byte 159
996//      ReWriteReal(path,value,start)
997//     
998//      SetDataFolder root:
999//End
1000
1001//function will re-write a real value (4bytes) to the header of a RAW data file
1002//to ensure re-readability, the real value must be written mimicking VAX binary format
1003//which is done in this function
1004//path is the full path:file;vers to the file
1005//value is the real value to write
1006//start is the position to move the file marker to, to begin writing
1007//--so start is actually the "end byte" of the previous value
1008//
1009//this procedure takes care of all file open/close pairs needed
1010//
1011Function ReWriteReal(path,value,start)
1012        String path
1013        Variable value,start
1014       
1015        //Print " in F(), path = " + path
1016        Variable refnum,int1,int2, value4
1017
1018//////
1019        value4 = 4*value
1020       
1021        Open/A/T="????TEXT" refnum as path
1022        //write IEEE FP, 4*desired value
1023        FSetPos refnum,start
1024        FBinWrite/B=3/F=4 refnum,value4         //write out as little endian
1025       
1026        //move to the end of the file
1027        FStatus refnum
1028        FSetPos refnum,V_logEOF
1029        //Print "Wrote end of header to " + num2str(V_filePOS)
1030       
1031        Close refnum
1032       
1033///////
1034        Open/R refnum as path
1035        //read back as two 16-bit integers
1036        FSetPos refnum,start
1037        FBinRead/B=2/F=2 refnum,int1    //read as big-endian
1038        FBinRead/B=2/F=2 refnum,int2
1039       
1040        //file was opened read-only
1041        //no need to move to the end of the file, just close it
1042       
1043        Close refnum
1044///////
1045        Open/A/T="????TEXT" refnum as path
1046        //write the two 16-bit integers, reversed
1047        FSetPos refnum,start
1048        FBinWrite/B=2/F=2 refnum,int2   //re-write as big endian
1049        FBinWrite/B=2/F=2 refnum,int1
1050       
1051        //move to the end of the file
1052        FStatus refnum
1053        FSetPos refnum,V_logEOF
1054        //Print "Wrote end of header to " + num2str(V_filePOS)
1055       
1056        Close refnum                            //at this point, it is as the VAX would have written it.
1057       
1058        Return(0)
1059End
1060
1061//rewrite a text field back to the header
1062// fname is the full path:name
1063// str is the CORRECT length - it will all be written - pad before sending
1064// start is the start byte
1065Function RewriteTextToHeader(fname,str,start)
1066        String fname,str
1067        Variable start
1068       
1069        Variable refnum
1070        Open/A/T="????TEXT" refnum as fname      //Open for writing! Move to EOF before closing!
1071        FSetPos refnum,start
1072        FBinWrite/F=0 refnum, str      //native object format (character)
1073        //move to the end of the file before closing
1074        FStatus refnum
1075        FSetPos refnum,V_logEOF
1076        //Print "Wrote end of header to " + num2str(V_filePOS)
1077        Close refnum
1078               
1079        return(0)
1080end
1081
1082//rewrite an integer field back to the header
1083// fname is the full path:name
1084// val is the integer value
1085// start is the start byte
1086Function RewriteIntegerToHeader(fname,val,start)
1087        String fname
1088        Variable val,start
1089       
1090        Variable refnum
1091        Open/A/T="????TEXT" refnum as fname      //Open for writing! Move to EOF before closing!
1092        FSetPos refnum,31
1093        FBinWrite/B=3/F=3 refnum, val      //write a 4-byte integer
1094        //move to the end of the file before closing
1095        FStatus refnum
1096        FSetPos refnum,V_logEOF
1097        //Print "Wrote end of header to " + num2str(V_filePOS)
1098        Close refnum
1099               
1100        return(0)
1101end
1102
1103// read specific bits of information from the header
1104// each of these operations MUST take care of open/close on their own
1105
1106Function/S getStringFromHeader(fname,start,num)
1107        String fname                            //full path:name
1108        Variable start,num              //starting byte and number of characters to read
1109       
1110        String str
1111        Variable refnum
1112        Open/R refNum as fname
1113        FSetPos refNum,start
1114        FReadLine/N=(num) refNum,str
1115        Close refnum
1116       
1117        return(str)
1118End
1119// file suffix (4 characters @ byte 19)
1120Function/S getSuffix(fname)
1121        String fname
1122       
1123        return(getStringFromHeader(fname,19,4))
1124End
1125
1126// sample label (60 characters @ byte 98)
1127Function/S getSampleLabel(fname)
1128        String fname
1129       
1130        return(getStringFromHeader(fname,98,60))
1131End
1132
1133// file creation date (20 characters @ byte 55)
1134Function/S getFileCreationDate(fname)
1135        String fname
1136       
1137        return(getStringFromHeader(fname,55,20))
1138End
1139
1140// read a single real value with GBLoadWave
1141Function getRealValueFromHeader(fname,start)
1142        String fname
1143        Variable start
1144
1145        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
1146       
1147        GBLoadStr += "/S="+num2str(start)+"/U=1" + "\"" + fname + "\""
1148        Execute GBLoadStr
1149        Wave w=$"tempGBWave0"
1150       
1151        return(w[0])
1152End
1153
1154//monitor count is at byte 39
1155Function getMonitorCount(fname)
1156        String fname
1157       
1158        return(getRealValueFromHeader(fname,39))
1159end
1160
1161//saved monitor count is at byte 43
1162Function getSavMon(fname)
1163        String fname
1164       
1165        return(getRealValueFromHeader(fname,43))
1166end
1167
1168//detector count is at byte 47
1169Function getDetCount(fname)
1170        String fname
1171       
1172        return(getRealValueFromHeader(fname,47))
1173end
1174
1175//Attenuator number is at byte 51
1176Function getAttenNumber(fname)
1177        String fname
1178       
1179        return(getRealValueFromHeader(fname,51))
1180end
1181
1182//transmission is at byte 158
1183Function getSampleTrans(fname)
1184        String fname
1185       
1186        return(getRealValueFromHeader(fname,158))
1187end
1188
1189//SampleThickness is at byte 162
1190Function getSampleThickness(fname)
1191        String fname
1192       
1193        return(getRealValueFromHeader(fname,162))
1194end
1195
1196//Sample Rotation Angle is at byte 170
1197Function getSampleRotationAngle(fname)
1198        String fname
1199       
1200        return(getRealValueFromHeader(fname,170))
1201end
1202
1203//temperature is at byte 186
1204Function getTemperature(fname)
1205        String fname
1206       
1207        return(getRealValueFromHeader(fname,186))
1208end
1209
1210//field strength is at byte 190
1211Function getFieldStrength(fname)
1212        String fname
1213       
1214        return(getRealValueFromHeader(fname,190))
1215end
1216
1217//beam xPos is at byte 252
1218Function getBeamXPos(fname)
1219        String fname
1220       
1221        return(getRealValueFromHeader(fname,252))
1222end
1223
1224//beam Y pos is at byte 256
1225Function getBeamYPos(fname)
1226        String fname
1227       
1228        return(getRealValueFromHeader(fname,256))
1229end
1230
1231//SDD is at byte 260
1232Function getSDD(fname)
1233        String fname
1234       
1235        return(getRealValueFromHeader(fname,260))
1236end
1237
1238//detector offset is at byte 264
1239Function getDetectorOffset(fname)
1240        String fname
1241       
1242        return(getRealValueFromHeader(fname,264))
1243end
1244
1245//Beamstop diameter is at byte 272
1246Function getBSDiameter(fname)
1247        String fname
1248       
1249        return(getRealValueFromHeader(fname,272))
1250end
1251
1252//source aperture diameter is at byte 280
1253Function getSourceApertureDiam(fname)
1254        String fname
1255       
1256        return(getRealValueFromHeader(fname,280))
1257end
1258
1259//sample aperture diameter is at byte 284
1260Function getSampleApertureDiam(fname)
1261        String fname
1262       
1263        return(getRealValueFromHeader(fname,284))
1264end
1265
1266//source AP to Sample AP distance is at byte 288
1267Function getSourceToSampleDist(fname)
1268        String fname
1269       
1270        return(getRealValueFromHeader(fname,288))
1271end
1272
1273//wavelength is at byte 292
1274Function getWavelength(fname)
1275        String fname
1276       
1277        return(getRealValueFromHeader(fname,292))
1278end
1279
1280//wavelength spread is at byte 296
1281Function getWavelengthSpread(fname)
1282        String fname
1283       
1284        return(getRealValueFromHeader(fname,296))
1285end
1286
1287//transmission detector count is at byte 388
1288Function getTransDetectorCounts(fname)
1289        String fname
1290       
1291        return(getRealValueFromHeader(fname,388))
1292end
1293
1294//////  integer values
1295
1296Function getIntegerFromHeader(fname,start)
1297        String fname                            //full path:name
1298        Variable start          //starting byte
1299       
1300        Variable refnum,val
1301        Open/R refNum as fname
1302        FSetPos refNum,start
1303        FBinRead/B=3/F=3 refnum,val
1304        Close refnum
1305       
1306        return(val)
1307End
1308
1309//total count time is at byte 31       
1310Function getCountTime(fname)
1311        String fname
1312        return(getIntegerFromHeader(fname,31))
1313end
1314
1315
1316//reads the wavelength from a reduced data file (not very reliable)
1317// - does not work with NSORTed files
1318// - only used in FIT/RPA (which itself is almost NEVER used...)
1319//
1320Function GetLambdaFromReducedData(tempName)
1321        String tempName
1322       
1323        String junkString
1324        Variable lambdaFromFile, fileVar
1325        lambdaFromFile = 6.0
1326        Open/R/P=catPathName fileVar as tempName
1327        FReadLine fileVar, junkString
1328        FReadLine fileVar, junkString
1329        FReadLine fileVar, junkString
1330        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
1331                FReadLine/N=11 fileVar, junkString
1332                FReadLine/N=10 fileVar, junkString
1333                lambdaFromFile = str2num(junkString)
1334        endif
1335        Close fileVar
1336       
1337        return(lambdaFromFile)
1338End
1339
1340/////   TRANSMISSION RELATED FUNCTIONS    ////////
1341//box coordinate are returned by reference
1342Function GetXYBoxFromFile(filename,x1,x2,y1,y2)
1343        String filename
1344        Variable &x1,&x2,&y1,&y2
1345       
1346        Variable refnum
1347        String tmpFile = FindValidFilename(filename)
1348               
1349        Open/R/P=catPathName refnum as tmpFile
1350        FSetPos refnum,478
1351        FBinRead/F=3/B=3 refnum, x1
1352        FBinRead/F=3/B=3 refnum, x2
1353        FBinRead/F=3/B=3 refnum, y1
1354        FBinRead/F=3/B=3 refnum, y2
1355        Close refnum
1356       
1357        return(0)
1358End
1359
1360//go find the file, open it and write 4 integers to the file
1361//in the positions for analysis.rows(2), .cols(2) = 4 unused 4byte integers
1362Function WriteXYBoxToHeader(filename,x1,x2,y1,y2)
1363        String filename
1364        Variable x1,x2,y1,y2
1365       
1366        Variable refnum
1367        Open/A/T="????TEXT" refnum as filename
1368        FSetPos refnum,478
1369        FBinWrite/F=3/B=3 refNum, x1
1370        FBinWrite/F=3/B=3 refNum, x2
1371        FBinWrite/F=3/B=3 refNum, y1
1372        FBinWrite/F=3/B=3 refNum, y2
1373        //move to the end of the file before closing
1374        FStatus refnum
1375        FSetPos refnum,V_logEOF
1376        Close refnum
1377       
1378        return(0)
1379End
Note: See TracBrowser for help on using the repository browser.