source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/ANSTO_DataReadWrite.ipf @ 665

Last change on this file since 665 was 588, checked in by srkline, 13 years ago

Added conditional compile instructions to some reduction procedure files that have only minor facility-specific changes. These changes are not significant enough to merit a separate facility file that must be maintained with essentially duplicate functions.

#define SYMBOL was attempted, but did not work since the symbols weren't actually defined until after the compile... and I couldn't figure out how to define - then compile. in additon, the table is static until Igor is quit - so multiple symbols could be defined, and compiling would fail.

So... the method now that appears to work is to put a dummy function for each facility in its facility specific "Includes" file. Then the conditional compilation checks for exists("function").

File size: 43.6 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
44        ReadHeaderAndData(filename)     //this is the full Path+file
45       
46        Return(0)
47End
48
49
50//function that does the guts of reading the binary data file
51//fname is the full path:name;vers required to open the file
52//
53// The final root:Packages:NIST:RAW:data wave is the real
54//neutron counts and can be directly operated on
55//
56// header information is put into three waves: integersRead, realsRead, and textRead
57// logicals in the header are currently skipped, since they are no use in the
58// data reduction process.
59//
60// The output is the three R/T/I waves that are filled at least with minimal values
61// and the detector data loaded into an array named "data"
62//
63// see documentation for the expected information in each element of the R/T/I waves
64// and the minimum set of information. These waves can be increased in length so that
65// more information can be accessed as needed (propagating changes...)
66//
67// called by multiple .ipfs (when the file name is known)
68//
69//
70// THIS FUNCTION DOES NOT NEED TO BE MODIFIED. ONLY THE DATA ACCESSORS NEED TO BE CONSTRUCTED
71//
72Function ReadHeaderAndData(fname)
73        String fname
74        //this function is for reading in RAW data only, so it will always put data in RAW folder
75        String curPath = "root:Packages:NIST:RAW"
76        SetDataFolder curPath           //use the full path, so it will always work
77        variable/g root:Packages:NIST:RAW:gIsLogScale = 0               //initial state is linear, keep this in RAW folder
78       
79        Variable refNum,integer,realval
80        String sansfname,textstr
81       
82        Make/D/O/N=23 $"root:Packages:NIST:RAW:IntegersRead"
83        Make/D/O/N=52 $"root:Packages:NIST:RAW:RealsRead"
84        Make/O/T/N=11 $"root:Packages:NIST:RAW:TextRead"
85        Make/O/N=7 $"root:Packages:NIST:RAW:LogicalsRead"
86
87        Wave intw=$"root:Packages:NIST:RAW:IntegersRead"
88        Wave realw=$"root:Packages:NIST:RAW:RealsRead"
89        Wave/T textw=$"root:Packages:NIST:RAW:TextRead"
90        Wave logw=$"root:Packages:NIST:RAW:LogicalsRead"
91       
92        // FILL IN 3 ARRAYS WITH HEADER INFORMATION FOR LATER USE
93        // THESE ARE JUST THE MINIMALLY NECESSARY VALUES
94       
95        // filename as stored in the file header
96        textw[0]= fname
97       
98        // date and time of collection
99        textw[1]= getFileCreationDate(fname)
100       
101        // run type identifier (this is a reader for RAW data)
102        textw[2]= "RAW"
103       
104        // user account identifier (currently used only for NCNR-specific operations)
105        textw[3]= ""
106
107        // sample label
108        textw[6]= getSampleLabel(fname)
109       
110        // identifier of detector type, useful for setting detector constants
111        //(currently used only for NCNR-specific operations)
112        textw[9]= ""
113
114        //total counting time in seconds
115        intw[2] = getCountTime(fname)
116       
117//      realw[1] = 0
118//      realw[6] = 0
119//      realw[7] = 0
120//      realw[8] = 0
121//      realw[9] = 0
122//      realw[19] = 0
123//      realw[22] = 0
124
125        // total monitor count
126        realw[0] = getMonitorCount(fname)
127       
128        // total detector count
129        realw[2] = getDetCount(fname)
130       
131        // attenuator number (NCNR-specific, your stub returns 0)
132        // may also be used to hold attenuator transmission (< 1)
133        realw[3] = getAttenNumber(fname)
134       
135        // sample transmission
136        realw[4] = getSampleTrans(fname)
137       
138        //sample thickness (cm)
139        realw[5] = getSampleThickness(fname)
140       
141        // following 6 values are for non-linear spatial corrections to a detector (RC timing)
142        // these values are set for a detctor that has a linear correspondence between
143        // pixel number and real-space distance
144        // 10 and 13 are the X and Y pixel dimensions, respectively (in mm!)
145        //(11,12 and 13,14 are set to values for a linear response, as from a new Ordela detector)
146        realw[10] = getDetectorPixelXSize(fname)
147        realw[11] = 10000
148        realw[12] = 0
149        realw[13] = getDetectorPixelYSize(fname)
150        realw[14] = 10000
151        realw[15] = 0
152       
153        // beam center X,Y on the detector (in units of pixel coordinates (1,N))
154        realw[16] = getBeamXPos(fname)
155        realw[17] = getBeamYPos(fname)
156       
157        // sample to detector distance (meters)
158        realw[18] = getSDD(fname)
159
160        // detector physical width (right now assumes square...) (in cm)
161        //realw[20] = 65
162        realw[20] = getPhysicalWidth(fname)
163       
164        // beam stop diameter (assumes circular) (in mm)
165        realw[21] = getBSDiameter(fname)
166       
167        // source aperture diameter (mm)
168        realw[23] = getSourceApertureDiam(fname)
169       
170        // sample aperture diameter (mm)
171        realw[24] = getSampleApertureDiam(fname)
172       
173        // source aperture to sample aperture distance
174        realw[25] = getSourceToSampleDist(fname)
175       
176        // wavelength (A)
177        realw[26] = getWavelength(fname)
178       
179        // wavelength spread (FWHM)
180        realw[27] = getWavelengthSpread(fname)
181       
182        // beam stop X-position (motor reading, approximate cm from zero position)
183        // currently NCNR-specific use to identify transmission measurements
184        // you return 0
185        realw[37] = 0
186
187// the actual data array, dimensions are set as globals in
188// InitFacilityGlobals()
189        NVAR XPix = root:myGlobals:gNPixelsX
190        NVAR YPix = root:myGlobals:gNPixelsX
191       
192        Make/D/O/N=(XPix,YPix) $"root:Packages:NIST:RAW:data"
193        WAVE data=$"root:Packages:NIST:RAW:data"
194
195        // fill the data array with the detector values
196        getDetectorData(fname,data)
197       
198        //keep a string with the filename in the RAW folder
199        String/G root:Packages:NIST:RAW:fileList = textw[0]
200       
201        Return 0
202
203End
204
205//****************
206//main entry procedure for reading a "WORK.DIV" file
207//displays a quick image of the  file, to check that it's correct
208//data is deposited in root:Packages:NIST:DIV data folder
209//
210// local, just for testing
211//
212Proc ReadWork_DIV()
213       
214        String fname = PromptForPath("Select detector sensitivity file")
215        ReadHeaderAndWork("DIV",fname)          //puts what is read in work.div
216       
217        String waveStr = "root:Packages:NIST:DIV:data"
218        NewImage/F/K=1/S=2 $waveStr
219        ModifyImage '' ctab= {*,*,YellowHot,0}
220       
221        String/G root:Packages:NIST:DIV:fileList = "WORK.DIV"
222       
223        SetDataFolder root:             //(redundant)
224End
225
226
227
228// Detector sensitivity files have the same header structure as RAW SANS data
229// as NCNR, just with a different data array (real, rather than integer data)
230//
231// So for your facility, make this reader specific to the format of whatever
232// file you use for a pixel-by-pixel division of the raw detector data
233// to correct for non-uniform sensitivities of the detector. This is typically a
234// measurement of water, plexiglas, or another uniform scattering sample.
235//
236// The data must be normalized to a mean value of 1
237//
238// called from ProtocolAsPanel.ipf
239//
240// type is "DIV" on input
241Function ReadHeaderAndWork(type,fname)
242        String type,fname
243       
244        //type is the desired folder to read the workfile to
245        //this data will NOT be automatically displayed
246        // gDataDisplayType is unchanged
247
248        String cur_folder = type
249        String curPath = "root:Packages:NIST:"+cur_folder
250        SetDataFolder curPath           //use the full path, so it will always work
251       
252        Variable refNum,integer,realval
253        String sansfname,textstr
254        Variable/G $(curPath + ":gIsLogScale") = 0              //initial state is linear, keep this in DIV folder
255       
256        Make/O/D/N=23 $(curPath + ":IntegersRead")
257        Make/O/D/N=52 $(curPath + ":RealsRead")
258        Make/O/T/N=11 $(curPath + ":TextRead")
259       
260        WAVE intw=$(curPath + ":IntegersRead")
261        WAVE realw=$(curPath + ":RealsRead")
262        WAVE/T textw=$(curPath + ":TextRead")
263       
264        // the actual data array, dimensions are set as globals in
265        // InitFacilityGlobals()
266        NVAR XPix = root:myGlobals:gNPixelsX
267        NVAR YPix = root:myGlobals:gNPixelsX
268
269        Make/O/D/N=(XPix,YPix) $(curPath + ":data")
270        WAVE data = $(curPath + ":data")
271       
272        // (1)
273        // fill in your reader for the header here so that intw, realw, and textW are filled in
274        // ? possibly a duplication of the raw data reader
275               
276        //(2)
277        // then fill in a reader for the data array that will DIVIDE your data
278        // to get the corrected values.
279        String dfName=""
280        variable err
281        err = hdfRead(fname, dfName)
282        Wave tempData = $dfName+":data:div"
283        data = tempData
284
285        //keep a string with the filename in the DIV folder
286        String/G $(curPath + ":fileList") = textw[0]
287       
288        //return the data folder to root
289        SetDataFolder root:
290       
291        Return(0)
292End
293
294Function WriteHeaderAndWork(type)
295        String type
296       
297        // your writer here
298        NVAR XPix = root:myGlobals:gNPixelsX
299        NVAR YPix = root:myGlobals:gNPixelsX   
300       
301        Wave wData=$("root:Packages:NIST:"+type+":data")
302       
303//      Variable refnum,ii=0,hdrBytes=516,a,b,offset
304        String fname=""
305//      Duplicate/O wData,tempData
306       
307        //changed for Quokka
308//      Redimension/S/N=(XPix*YPix) tempData
309//      tempData *= 4
310       
311        PathInfo/S catPathName
312        fname = DoSaveFileDialog("Save data as")          //won't actually open the file
313        If(cmpstr(fname,"")==0)
314                //user cancel, don't write out a file
315          Close/A
316          Abort "no data file was written"
317        Endif
318       
319        variable fileID
320        HDF5CreateFile /O fileID as fname
321       
322        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
323        //Make /N=(1,1) wTransmission
324        String groupName = "/data"
325        String varName = "div"
326        // your code returning value
327        variable err
328        err = hdfWrite(fname, groupName, varName, wData)
329
330        // KillWaves wData, tempData
331        return(0)
332End
333
334
335
336/////   ASC FORMAT READER  //////
337/////   FOR WORKFILE MATH PANEL //////
338//
339//function to read in the ASC output of SANS reduction
340// currently the file has 20 header lines, followed by a single column
341// of 16384 values, Data is written by row, starting with Y=1 and X=(1->128)
342//
343//returns 0 if read was ok
344//returns 1 if there was an error
345//
346// called by WorkFileUtils.ipf
347//
348//
349// If the ASC data was generated by the NCNR data writer, then
350// NOTHING NEEDS TO BE CHANGED HERE
351//
352Function ReadASCData(fname,destPath)
353        String fname, destPath
354        //this function is for reading in ASCII data so put data in user-specified folder
355        SetDataFolder "root:Packages:NIST:"+destPath
356
357        NVAR pixelsX = root:myGlobals:gNPixelsX
358        NVAR pixelsY = root:myGlobals:gNPixelsY
359        Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20
360        String str=""
361        //data is initially linear scale
362        Variable/G :gIsLogScale=0
363        Make/O/T/N=(numHdrLines) hdrLines
364        Make/O/D/N=(pixelsX*pixelsY) data                       //,linear_data
365       
366        //full filename and path is now passed in...
367        //actually open the file
368//      SetDataFolder destPath
369        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
370        if(refnum==0)           //FNF error, get out
371                DoAlert 0,"Could not find file: "+fname
372                Close/A
373                SetDataFolder root:
374                return(1)
375        endif
376        if(V_flag!=0)
377                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
378                Close/A
379                SetDataFolder root:
380                return(1)
381        Endif
382        //
383        for(ii=0;ii<numHdrLines;ii+=1)          //read (or skip) 18 header lines
384                FReadLine refnum,str
385                hdrLines[ii]=str
386        endfor
387        //     
388        Close refnum
389       
390//      SetDataFolder destPath
391        LoadWave/Q/G/D/N=temp fName
392        Wave/Z temp0=temp0
393        data=temp0
394        Redimension/N=(pixelsX,pixelsY) data            //,linear_data
395       
396        //linear_data = data
397       
398        KillWaves/Z temp0
399       
400        //return the data folder to root
401        SetDataFolder root:
402       
403        Return(0)
404End
405
406// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
407// pay attention to what is/not to be trusted due to "fake" information.
408// uses what it can from the header lines from the ASC file (hdrLines wave)
409//
410// destFolder is of the form "myGlobals:WorkMath:AAA"
411//
412//
413// called by WorkFileUtils.ipf
414//
415// If the ASC data was generated by the NCNR data writer, then
416// NOTHING NEEDS TO BE CHANGED HERE
417//
418Function FillFakeHeader_ASC(destFolder)
419        String destFolder
420        Make/O/D/N=23 $("root:Packages:NIST:"+destFolder+":IntegersRead")
421        Make/O/D/N=52 $("root:Packages:NIST:"+destFolder+":RealsRead")
422        Make/O/T/N=11 $("root:Packages:NIST:"+destFolder+":TextRead")
423       
424        Wave intw=$("root:Packages:NIST:"+destFolder+":IntegersRead")
425        Wave realw=$("root:Packages:NIST:"+destFolder+":RealsRead")
426        Wave/T textw=$("root:Packages:NIST:"+destFolder+":TextRead")
427       
428        //Put in appropriate "fake" values
429        //parse values as needed from headerLines
430        Wave/T hdr=$("root:Packages:NIST:"+destFolder+":hdrLines")
431        Variable monCt,lam,offset,sdd,trans,thick
432        Variable xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam
433        String detTyp=""
434        String tempStr="",formatStr="",junkStr=""
435        formatStr = "%g %g %g %g %g %g"
436        tempStr=hdr[3]
437        sscanf tempStr, formatStr, monCt,lam,offset,sdd,trans,thick
438//      Print monCt,lam,offset,sdd,trans,thick,avStr,step
439        formatStr = "%g %g %g %g %g %g %g %s"
440        tempStr=hdr[5]
441        sscanf tempStr,formatStr,xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
442//      Print xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
443       
444        realw[16]=xCtr          //xCtr(pixels)
445        realw[17]=yCtr  //yCtr (pixels)
446        realw[18]=sdd           //SDD (m)
447        realw[26]=lam           //wavelength (A)
448        //
449        // necessary values
450        realw[10]=5                     //detector calibration constants, needed for averaging
451        realw[11]=10000
452        realw[12]=0
453        realw[13]=5
454        realw[14]=10000
455        realw[15]=0
456        //
457        // used in the resolution calculation, ONLY here to keep the routine from crashing
458        realw[20]=65            //det size
459        realw[27]=dlam  //delta lambda
460        realw[21]=bsDiam        //BS size
461        realw[23]=a1            //A1
462        realw[24]=a2    //A2
463        realw[25]=a1a2Dist      //A1A2 distance
464        realw[4]=trans          //trans
465        realw[3]=0              //atten
466        realw[5]=thick          //thick
467        //
468        //
469        realw[0]=monCt          //def mon cts
470
471        // fake values to get valid deadtime and detector constants
472        //
473        textw[9]=detTyp+"  "            //6 characters 4+2 spaces
474        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
475       
476        //set the string values
477        formatStr="FILE: %s CREATED: %s"
478        sscanf hdr[0],formatStr,tempStr,junkStr
479//      Print tempStr
480//      Print junkStr
481        String/G $("root:Packages:NIST:"+destFolder+":fileList") = tempStr
482        textw[0] = tempStr              //filename
483        textw[1] = junkStr              //run date-time
484       
485        //file label = hdr[1]
486        tempStr = hdr[1]
487        tempStr = tempStr[0,strlen(tempStr)-2]          //clean off the last LF
488//      Print tempStr
489        textW[6] = tempStr      //sample label
490       
491        return(0)
492End
493
494
495///////// ACCESSORS FOR WRITING DATA TO HEADER  /////////
496/////
497
498// Write* routines all must:
499// (1) open file "fname". fname is a full file path and name to the file on disk
500// (2) write the specified value to the header at the correct location in the file
501// (3) close the file
502
503
504
505//whole transmission is NCNR-specific right now
506// leave this stub empty
507Function WriteWholeTransToHeader(fname,wholeTrans)
508        String fname
509        Variable wholeTrans
510       
511        String groupName = "/entry1/reduce"
512        variable err
513       
514        Wave wCounts
515        Make /N=(1,1) wWholeTrans
516               
517        wWholeTrans[0] = wholeTrans
518       
519        String varName = "wholeTransmission"   
520        err = hdfWrite(fname, groupName, varName,wWholeTrans)
521
522        KillWaves wWholeTrans
523       
524        //err not handled here
525        return(0)       
526End
527
528//box sum counts is a real value
529// used for transmission calculation module
530Function WriteBoxCountsToHeader(fname,counts)
531        String fname
532        Variable counts
533       
534        // do nothing if not using NCNR Transmission module
535       
536        String groupName = "/entry1/reduce"
537        variable err
538       
539        Wave wCounts
540        Make /N=(1,1) wCounts
541               
542        wCounts[0] = counts
543       
544        String varName = "boxCounts"   
545        err = hdfWrite(fname, groupName, varName,wCounts)
546
547        KillWaves wCounts
548       
549        //err not handled here
550        return(0)       
551End
552
553//beam stop X-position
554// used for transmission module to manually tag transmission files
555Function WriteBSXPosToHeader(fname,xpos)
556        String fname
557        Variable xpos
558       
559        // do nothing if not using NCNR Transmission module
560       
561        return(0)
562End
563
564
565
566
567
568//attenuator number (not its transmission)
569// if your beam attenuation is indexed in some way, use that number here
570// if not, write a 1 to the file here as a default
571//
572Function WriteAttenNumberToHeader(fname,num)
573        String fname
574        Variable num
575       
576        // your code here, default of 1
577       
578        return(0)
579End
580
581// total monitor count during data collection
582Function WriteMonitorCountToHeader(fname,num)
583        String fname
584        Variable num
585       
586        // your code here
587       
588        return(0)
589End
590
591//total detector count
592Function WriteDetectorCountToHeader(fname,num)
593        String fname
594        Variable num
595       
596        // your code here
597       
598        return(0)
599End
600
601//transmission detector count
602// (currently unused in data reduction)
603Function WriteTransDetCountToHeader(fname,num)
604        String fname
605        Variable num
606       
607        // do nothing for now
608       
609        return(0)
610End
611
612
613
614//temperature of the sample (C)
615Function WriteTemperatureToHeader(fname,num)
616        String fname
617        Variable num
618       
619        //  your code here
620       
621        return(0)
622End
623
624//magnetic field (Oe)
625Function WriteMagnFieldToHeader(fname,num)
626        String fname
627        Variable num
628       
629        // your code here
630       
631        return(0)
632End
633
634//lateral detector offset (centimeters)
635Function WriteDetectorOffsetToHeader(fname,num)
636        String fname
637        Variable num
638       
639        //your code here
640       
641        return(0)
642End
643
644
645
646
647// physical dimension of detector x-pixel (mm)
648Function WriteDetPixelXToHeader(fname,num)
649        String fname
650        Variable num
651       
652        //your code here
653       
654        return(0)
655end
656
657// physical dimension of detector y-pixel (mm)
658Function WriteDetPixelYToHeader(fname,num)
659        String fname
660        Variable num
661       
662        //your code here
663       
664        return(0)
665end
666
667// sample label string
668Function WriteSamLabelToHeader(fname,str)
669        String fname,str
670       
671        // your code here
672
673        return(0)
674End
675
676// total counting time (seconds)
677Function WriteCountTimeToHeader(fname,num)
678        String fname
679        Variable num
680       
681        // your code here
682       
683        return(0)
684End
685
686
687
688//////// ACCESSORS FOR READING DATA FROM THE HEADER  //////////////
689//
690// read specific bits of information from the header
691// each of these operations MUST take care of open/close on their own
692//
693// fname is the full path and filname to the file on disk
694// return values are either strings or real values as appropriate
695//
696//////
697
698
699// function that reads in the 2D detector data and fills the array
700// data[nx][ny] with the data values
701// fname is the full name and path to the data file for opening and closing
702//
703//
704Function getDetectorData(fname,data)
705        String fname
706        Wave data
707        NVAR XPix = root:myGlobals:gNPixelsX
708       
709        // your reader here
710        variable err
711        string dfName = ""
712        err = hdfRead(fname, dfName)
713        if(err)
714                return 0
715        endif
716
717        Wave hmm_xy = $(dfName+":entry1:data:hmm_xy")
718       
719        //redimension /I /N = (dimsize(hmm_xy, 2), dimsize(hmm_xy, 1)), data
720        //nha. Count arrays need to be floating point, since the data will be divided, normalised etc.
721        redimension /N = (dimsize(hmm_xy, 2), dimsize(hmm_xy, 1)), data
722        data[][] = hmm_xy[0][q][p]
723       
724        //nha workaround. for wrongly dimensioned Quokka data 191x192
725        variable x_dim = dimsize(data,0)
726        if (x_dim!=XPix)
727                //redimension to add an extra row(s) to the data
728                redimension /I /N = (XPix,-1) data
729                //copy row 190 to row 191
730                data[191][] = data[190][q]
731        endif   
732        // end workaround
733               
734        KillWaves hmm_xy
735       
736       
737        return(0)
738End
739
740// file suffix (NCNR data file name specific)
741// return null string
742Function/S getSuffix(fname)
743        String fname
744       
745        return("")
746End
747
748// associated file suffix (for transmission)
749// NCNR Transmission calculation specific
750// return null string
751Function/S getAssociatedFileSuffix(fname)
752        String fname
753       
754        return("")
755End
756
757// sample label
758Function/S getSampleLabel(fname)
759        String fname
760        String str
761       
762        // your code, returning str
763        variable err
764        string dfName = ""
765        err = hdfRead(fname, dfName)
766        //err not handled here
767       
768        Wave/T wSampleName = $dfname+":entry1:sample:name"
769        str = wSampleName[0]
770        KillWaves wSampleName
771       
772        return(str)
773End
774
775// file creation date
776Function/S getFileCreationDate(fname)
777        String fname
778        String str
779       
780        // your code, returning str
781        variable err
782        string dfName = ""
783        err = hdfRead(fname, dfName)
784        //err not handled here
785       
786        Wave/T wStartTime = $dfName+":entry1:start_time"
787        str = wStartTime[0]
788        KillWaves wStartTime
789       
790        return(str)
791End
792
793
794//monitor count
795Function getMonitorCount(fname)
796        String fname
797        Variable value
798       
799        // your code returning value
800        variable err
801        string dfName = ""
802        err = hdfRead(fname, dfName)
803        //err not handled here
804       
805        Wave wCounts = $dfName+":entry1:monitor:bm1_counts"
806        value = wCounts[0]
807        KillWaves wCounts
808       
809        return(value)
810end
811
812//saved monitor count
813// NCNR specific for pre-processed data, never used
814// return 0
815Function getSavMon(fname)
816        String fname
817       
818        Variable value
819       
820        // your code returning value
821        //??? to do. Is this required if 'never used'? nha
822       
823        return(0)
824end
825
826//total detector count
827Function getDetCount(fname)
828        String fname
829        Variable value
830       
831        // your code returning value
832        variable err
833        string dfName = ""
834        err = hdfRead(fname, dfName)
835        //err not handled here
836
837        Wave wCounts = $(dfName+":entry1:data:total_counts")
838        value = wCounts[0]
839        KillWaves wCounts
840       
841        return(value)
842end
843
844//Attenuator number, return 1 if your attenuators are not
845// indexed by number
846Function getAttenNumber(fname)
847        String fname
848        Variable value
849        Variable att, err
850        string dfName = ""
851               
852        err = hdfRead(fname, dfName)
853        //err not handled here
854
855        Wave wAttrotdeg = $(dfName+":entry1:instrument:parameters:derived_parameters:AttRotDeg")
856        value = wAttrotdeg[0]
857        att = round(value)/30
858        KillWaves wAttrotdeg
859        return(att)
860end
861
862//transmission
863Function getSampleTrans(fname)
864        String fname
865       
866        Variable value
867       
868        // your code returning value
869        variable err
870        string dfName = ""
871        err = hdfRead(fname, dfName)
872        //err not handled here
873
874        Wave wTransmission = $(dfName+":entry1:data:Transmission")
875        value = wTransmission[0]
876        KillWaves wTransmission
877               
878        return(value)
879end
880
881//sample transmission (0<T<=1)
882Function WriteTransmissionToHeader(fname,trans)
883        String fname
884        Variable trans
885       
886        // your writer here
887        Wave wTransmission
888        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
889        Make /N=(1,1) wTransmission
890        String groupName = "/entry1/data"
891        String varName = "Transmission"
892        wTransmission[0] = trans //
893        // your code returning value
894        variable err
895        err = hdfWrite(fname, groupName, varName, wTransmission)
896        KillWaves wTransmission
897        //err not handled here
898               
899        return(0)
900End
901
902//box counts from stored transmission calculation
903// return 0 if not using NCNR transmission module
904Function getBoxCounts(fname)
905        String fname
906        Variable value
907       
908        // do nothing if not using NCNR Transmission module
909        variable err
910        string dfName = ""
911        err = hdfRead(fname, dfName)
912        //err not handled here
913
914        Wave wBoxCounts = $(dfName+":entry1:reduce:boxCounts")
915        value = wBoxCounts[0]
916        KillWaves wBoxCounts
917       
918        return(value)
919end
920
921//whole detector transmission
922// return 0 if not using NCNR transmission module
923Function getSampleTransWholeDetector(fname)
924        String fname
925        Variable value
926       
927        // your code returning value
928        // ??? don't know what to put here. nha
929        value=0
930        return(value)
931end
932
933//SampleThickness in centimeters
934Function getSampleThickness(fname)
935        String fname
936        Variable value
937
938        // your code returning value
939       
940        variable err
941        string dfName = ""
942        err = hdfRead(fname, dfName)
943        //err not handled here
944
945        Wave wThickness = $(dfName+":entry1:sample:thickness") //does not exist ???
946        value = wThickness[0]
947        //value = 1 //??? temporary fix. nha
948        KillWaves wThickness
949       
950        return(value)
951end
952
953//sample thickness in cm
954Function WriteThicknessToHeader(fname,thickness)
955        String fname
956        Variable thickness
957       
958        // your writer here
959        Wave wThickness
960        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
961        Make /N=(1,1) wThickness
962        String groupName = "/entry1/sample"
963        String varName = "thickness"
964        wThickness[0] = thickness //
965        // your code returning value
966        variable err
967        err = hdfWrite(fname, groupName, varName, wThickness) //does not exist ???
968        KillWaves wThickness
969        //err not handled here
970               
971        return(0)
972End
973
974//Sample Rotation Angle (degrees)
975Function getSampleRotationAngle(fname)
976        String fname
977        Variable value
978       
979        // your code returning value
980        variable err
981        string dfName = ""
982        err = hdfRead(fname, dfName)
983        //err not handled here
984
985        Wave wSample_rotation_angle = $(dfName+":entry1:sample:sample_theta") //is this correct
986        value = wSample_rotation_angle[0]
987        KillWaves wSample_rotation_angle
988               
989        return(value)
990end
991
992//temperature (C)
993Function getTemperature(fname)
994        String fname
995       
996        Variable value
997       
998        // your code returning value
999       
1000        return(value)
1001end
1002
1003//field strength (Oe)
1004Function getFieldStrength(fname)
1005        String fname
1006       
1007        Variable value
1008       
1009        // your code returning value
1010       
1011        return(value)
1012end
1013
1014//center of beam xPos in pixel coordinates
1015Function getBeamXPos(fname)
1016        String fname
1017        Variable value
1018        // your code returning value
1019        variable err
1020        string dfName = ""
1021        err = hdfRead(fname, dfName)
1022        //err not handled here
1023
1024        Wave wBeamXPos = $(dfName+":entry1:instrument:parameters:BeamCenterX") //is this correct
1025        value = wBeamXPos[0]   
1026        KillWaves wBeamXPos
1027       
1028        return(value)   
1029
1030end
1031
1032//beam center X pixel location (detector coordinates)
1033Function WriteBeamCenterXToHeader(fname,beamCenterX)
1034        String fname
1035        Variable beamCenterX
1036       
1037        // your writer here
1038        Wave wBeamCenterX
1039        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1040        Make /N=(1,1) wBeamCenterX
1041        String groupName = "/entry1/instrument/parameters"
1042        String varName = "BeamCenterX"
1043        wBeamCenterX[0] = beamCenterX //
1044        // your code returning value
1045        variable err
1046        err = hdfWrite(fname, groupName, varName, wBeamCenterX)
1047        KillWaves wBeamCenterX
1048        //err not handled here
1049       
1050        return(0)
1051End
1052
1053//center of beam Y pos in pixel coordinates
1054Function getBeamYPos(fname)
1055        String fname
1056        Variable value
1057        // your code returning value
1058        variable err
1059        string dfName = ""
1060        err = hdfRead(fname, dfName)
1061        //err not handled here
1062
1063        Wave wBeamYPos = $(dfName+":entry1:instrument:parameters:BeamCenterZ") //is this correct
1064        value = wBeamYPos[0]   
1065        KillWaves wBeamYPos
1066               
1067        return(value)
1068end
1069
1070//beam center Y pixel location (detector coordinates)
1071Function WriteBeamCenterYToHeader(fname,beamCenterY)
1072        String fname
1073        Variable beamCenterY
1074       
1075        // your writer here
1076        Wave wBeamCenterY
1077        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1078        Make /N=(1,1) wBeamCenterY
1079        String groupName = "/entry1/instrument/parameters"
1080        String varName = "BeamCenterZ"
1081        wBeamCenterY[0] = beamCenterY //
1082        // your code returning value
1083        variable err
1084        err = hdfWrite(fname, groupName, varName, wBeamCenterY)
1085        KillWaves wBeamCenterY
1086        //err not handled here
1087
1088        return(0)
1089End
1090
1091
1092//sample to detector distance (meters)
1093Function getSDD(fname)
1094        String fname
1095        Variable value
1096        // your code returning value
1097        variable err
1098        string dfName = ""
1099        err = hdfRead(fname, dfName)
1100        //err not handled here
1101
1102        //workaround for bad HDF5 dataset
1103        String tempDF = dfName+":entry1:instrument:parameters:L2mm"
1104        if(Exists(tempDF))
1105                Wave wSourceToDetectorDist = $(dfName+":entry1:instrument:parameters:L2mm") //is this correct
1106        else
1107                Wave wSourceToDetectorDist = $(dfName+":entry1:instrument:parameters:derived_parameters:L2mm") //is this correct
1108        endif
1109       
1110        value = wSourceToDetectorDist[0]/1000   
1111        KillWaves wSourceToDetectorDist
1112               
1113        return(value)
1114end
1115
1116//sample to detector distance (meters)
1117Function WriteSDDToHeader(fname,sdd)
1118        String fname
1119        Variable sdd
1120       
1121// your writer here
1122        Wave wSDD
1123        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1124        Make /N=(1,1) wSDD
1125//      String groupName = "/entry1/instrument/parameters/derived_parameters"
1126        String groupName = "/entry1/instrument/parameters"
1127        String varName = "L2mm"
1128        wSDD[0] = sdd * 1000 //
1129        // your code returning value
1130        variable err
1131        err = hdfWrite(fname, groupName, varName, wSDD)
1132        KillWaves wSDD
1133        //err not handled here
1134       
1135        return(0)
1136End
1137
1138//lateral detector offset (centimeters)
1139Function getDetectorOffset(fname)
1140        String fname
1141        Variable value
1142        // your code returning value
1143        variable err
1144        string dfName = ""
1145        err = hdfRead(fname, dfName)
1146        //err not handled here
1147
1148        Wave wDetectorOffset = $(dfName+":entry1:instrument:detector:detector_x") //is this correct
1149        value = wDetectorOffset[0]/10
1150        KillWaves wDetectorOffset
1151       
1152        return(value)
1153end
1154
1155//Beamstop diameter (millimeters)
1156Function getBSDiameter(fname)
1157        String fname
1158        Variable value
1159        // your code returning value
1160        variable err
1161        string dfName = ""
1162        err = hdfRead(fname, dfName)
1163        //err not handled here
1164
1165        Wave wBSdiameter = $(dfName+":entry1:instrument:parameters:BSXmm") //is this correct
1166        value = wBSdiameter[0]
1167        KillWaves wBSdiameter
1168       
1169        return(value)   
1170end
1171
1172//beam stop diameter (millimeters)
1173Function WriteBeamStopDiamToHeader(fname,bs)
1174        String fname
1175        Variable bs     
1176       
1177        // your writer here
1178        Wave wBS
1179        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1180        Make /N=(1,1) wBS
1181        String groupName = "/entry1/instrument/parameters"
1182        String varName = "BSXmm"
1183        wBS[0] = bs //
1184        // your code returning value
1185        variable err
1186        err = hdfWrite(fname, groupName, varName, wBS)
1187        KillWaves wBS
1188        //err not handled here
1189        return(0)
1190End
1191
1192//source aperture diameter (millimeters)
1193Function getSourceApertureDiam(fname)
1194        String fname
1195        Variable value
1196        // your code returning value
1197        variable err
1198        string dfName = ""
1199        err = hdfRead(fname, dfName)
1200        //err not handled here
1201
1202        Wave wSourceApertureDiam = $(dfName+":entry1:instrument:parameters:derived_parameters:EApXmm") //is this correct
1203        value = wSourceApertureDiam[0]
1204        KillWaves wSourceApertureDiam
1205       
1206        return(value)
1207end
1208
1209//Source Aperture diameter (millimeters)
1210Function WriteSourceApDiamToHeader(fname,source)
1211        String fname
1212        Variable source
1213       
1214        // your writer here
1215        Wave wsource
1216        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1217        Make /N=(1,1) wsource
1218        String groupName = "/entry1/instrument/parameters/derived_parameters"
1219        String varName = "EApXmm"
1220        wsource[0] = source //
1221        // your code returning value
1222        variable err
1223        err = hdfWrite(fname, groupName, varName, wsource)
1224        KillWaves wsource
1225        //err not handled here
1226        return(0)
1227End
1228
1229//sample aperture diameter (millimeters)
1230Function getSampleApertureDiam(fname)
1231        String fname
1232        Variable value
1233        // your code returning value
1234        variable err
1235        string dfName = ""
1236        err = hdfRead(fname, dfName)
1237        //err not handled here
1238
1239        Wave wSampleApertureDiam = $(dfName+":entry1:instrument:sample_aperture:geometry:shape:SApXmm") //is this correct
1240        value = wSampleApertureDiam[0]
1241        KillWaves wSampleApertureDiam
1242
1243        return(value)   
1244end
1245
1246//Sample Aperture diameter (millimeters)
1247Function WriteSampleApDiamToHeader(fname,source)
1248        String fname
1249        Variable source
1250       
1251        // your writer here
1252        Wave wsource
1253        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1254        Make /N=(1,1) wsource
1255        String groupName = "/entry1/instrument/sample_aperture/geometry/shape"
1256        String varName = "SApXmm"
1257        wsource[0] = source //
1258        // your code returning value
1259        variable err
1260        err = hdfWrite(fname, groupName, varName, wsource)
1261        KillWaves wsource
1262        //err not handled here
1263        return(0)
1264End
1265
1266//source AP to Sample AP distance (meters)
1267Function getSourceToSampleDist(fname)
1268        String fname
1269       
1270        Variable value
1271       
1272        // your code returning value
1273        variable err
1274        string dfName = ""
1275               
1276        err = hdfRead(fname, dfName)
1277        //err not handled here
1278       
1279        //workaround for bad HDF5 dataset
1280        String tempDF = dfName+":entry1:instrument:parameters:L1mm"
1281        if(Exists(tempDF))
1282                Wave wSourceToSampleDist = $(dfName+":entry1:instrument:parameters:L1mm") //is this correct
1283        else
1284                Wave wSourceToSampleDist = $(dfName+":entry1:instrument:parameters:derived_parameters:L1mm") //is this correct
1285        endif
1286       
1287        value = wSourceToSampleDist[0]/1000
1288        KillWaves wSourceToSampleDist   
1289               
1290        return(value)
1291end
1292
1293//Source aperture to sample aperture distance (meters)
1294Function WriteSrcToSamDistToHeader(fname,SSD)
1295        String fname
1296        Variable SSD
1297       
1298// your writer here
1299        Wave wSSD
1300        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1301        Make /N=(1,1) wSSD
1302//      String groupName = "/entry1/instrument/parameters/derived_parameters"
1303        String groupName = "/entry1/instrument/parameters"
1304        String varName = "L1mm"
1305        wSSD[0] = SSD * 1000 //input in metres, converted to mm for saving to file.
1306        // your code returning value
1307        variable err
1308        err = hdfWrite(fname, groupName, varName, wSSD)
1309        KillWaves wSSD
1310        //err not handled here
1311       
1312        return(0)
1313End
1314
1315//wavelength (Angstroms)
1316Function getWavelength(fname)
1317        String fname
1318        Variable value
1319        // your code returning value
1320        variable err
1321        string dfName = ""
1322        err = hdfRead(fname, dfName)
1323        //err not handled here
1324
1325        Wave wWavelength = $(dfName+":entry1:data:LambdaA") //is this correct
1326        value = wWavelength[0] 
1327        KillWaves wWavelength
1328       
1329        return(value)
1330end
1331
1332//wavelength (Angstroms)
1333Function WriteWavelengthToHeader(fname,wavelength)
1334        String fname
1335        Variable wavelength
1336       
1337        // your writer here
1338        Wave wWavelength
1339        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1340        Make /N=(1,1) wWavelength
1341        String groupName = "/entry1/data"
1342        String varName = "LambdaA"
1343        wWavelength[0] = wavelength //
1344        // your code returning value
1345        variable err
1346        err = hdfWrite(fname, groupName, varName, wWavelength)
1347       
1348        //and because Bill Hamilton is not happy with the NeXus naming, we write it to 2 other places
1349        groupName = "/entry1/instrument/parameters"
1350        err = hdfWrite(fname, groupName, varName, wWavelength)
1351        //velocity_selector group causes Igor crash
1352        //groupName = "/entry1/instrument/velocity_selector"
1353        //err = hdfWrite(fname, groupName, varName, wWavelength)
1354       
1355        KillWaves wWavelength
1356        //err not handled here
1357
1358        return(0)
1359End
1360
1361
1362
1363//wavelength spread (FWHM)
1364Function getWavelengthSpread(fname)
1365        String fname
1366       
1367        Variable value
1368       
1369        // your code returning value
1370        variable err
1371        string dfName = ""
1372        err = hdfRead(fname, dfName)
1373        //err not handled here
1374       
1375        //velocity_selector group causes Igor crash
1376        //Wave wWavelengthSpread = $(dfName+":entry1:instrument:velocity_selector:LambdaResFWHM_percent") //is this correct
1377        Wave wWavelengthSpread = $(dfName+":entry1:instrument:parameters:LambdaResFWHM_percent") //is this correct
1378
1379        value = wWavelengthSpread[0]   
1380        KillWaves wWavelengthSpread
1381       
1382        return(value)
1383end
1384
1385//wavelength spread (FWHM)
1386Function WriteWavelengthDistrToHeader(fname,wavelengthSpread)
1387        String fname
1388        Variable wavelengthSpread
1389       
1390        // your writer here
1391        Wave wWavelengthSpread
1392        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1393        Make /N=(1,1) wWavelengthSpread
1394        //velocity_selector group causes Igor crash
1395        //String groupName = "/entry1/instrument/velocity_selector"
1396        String groupName = "/entry1/instrument/parameters"
1397        String varName = "LambdaResFWHM_percent"
1398
1399        wWavelengthSpread[0] = wavelengthSpread
1400        // your code returning value
1401        variable err
1402        err = hdfWrite(fname, groupName, varName, wWavelengthSpread)
1403        KillWaves wWavelengthSpread
1404        //err not handled here
1405               
1406        return(0)
1407End
1408
1409// physical x-dimension of a detector pixel, in mm
1410Function getDetectorPixelXSize(fname)
1411        String fname
1412        Variable value
1413       
1414        // your code here returning value
1415        variable err
1416        string dfName = ""
1417        err = hdfRead(fname, dfName)
1418        //err not handled here
1419
1420        Wave wActiveArea = $(dfName+":entry1:instrument:detector:active_height")
1421        Wave w_x_bin = $(dfName+":entry1:instrument:detector:x_bin")
1422        Variable numPixels = dimsize(w_x_bin, 0)
1423        value = wActiveArea[0]/numPixels
1424        KillWaves wActiveArea
1425        KillWaves w_x_bin
1426       
1427        return(value)
1428end
1429
1430// physical y-dimension of a detector pixel, in mm
1431Function getDetectorPixelYSize(fname)
1432        String fname
1433        Variable value
1434       
1435        // your code here returning value
1436        variable err
1437        string dfName = ""
1438        err = hdfRead(fname, dfName)
1439        //err not handled here
1440
1441        Wave wActiveArea = $(dfName+":entry1:instrument:detector:active_width")
1442        Wave w_y_bin = $(dfName+":entry1:instrument:detector:y_bin")
1443        Variable numPixels = dimsize(w_y_bin, 0)
1444        value = wActiveArea[0]/numPixels
1445        KillWaves wActiveArea
1446        KillWaves w_y_bin
1447                       
1448        return(value)
1449end
1450
1451//transmission detector count (unused, return 0)
1452//
1453Function getTransDetectorCounts(fname)
1454        String fname
1455       
1456        Variable value
1457       
1458        // your code returning value
1459       
1460        return(0)
1461end
1462
1463
1464//total count time (seconds)
1465Function getCountTime(fname)
1466        String fname
1467        Variable value
1468        // your code returning value
1469        variable err
1470        string dfName = ""
1471        err = hdfRead(fname, dfName)
1472        //err not handled here
1473
1474        Wave wTime1 = $(dfName+":entry1:monitor:bm1_time")
1475        value = wTime1[0]       
1476        KillWaves wTime1
1477       
1478        return(value)
1479end
1480
1481
1482Function getPhysicalWidth(fname)
1483        String fname
1484        Variable value
1485        // your code returning value
1486        variable err
1487        string dfName = ""
1488        err = hdfRead(fname, dfName)
1489        //err not handled here
1490
1491        Wave wPhysicalWidth = $(dfName+":entry1:instrument:detector:active_width")
1492        value = wPhysicalWidth[0]/10
1493        KillWaves wPhysicalWidth
1494               
1495        return(value)
1496end
1497
1498
1499//reads the wavelength from a reduced data file (not very reliable)
1500// - does not work with NSORTed files
1501// - only used in FIT/RPA (which itself is almost NEVER used...)
1502//
1503// DOES NOT NEED TO BE CHANGED IF USING NCNR DATA WRITER
1504Function GetLambdaFromReducedData(tempName)
1505        String tempName
1506       
1507        String junkString
1508        Variable lambdaFromFile, fileVar
1509        lambdaFromFile = 6.0
1510        Open/R/P=catPathName fileVar as tempName
1511        FReadLine fileVar, junkString
1512        FReadLine fileVar, junkString
1513        FReadLine fileVar, junkString
1514        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
1515                FReadLine/N=11 fileVar, junkString
1516                FReadLine/N=10 fileVar, junkString
1517                lambdaFromFile = str2num(junkString)
1518        endif
1519        Close fileVar
1520       
1521        return(lambdaFromFile)
1522End
1523
1524/////   TRANSMISSION RELATED FUNCTIONS    ////////
1525//box coordinate are returned by reference
1526//
1527// box to sum over is bounded (x1,y1) to (x2,y2)
1528//
1529// this function returns the bounding coordinates as stored in
1530// the header
1531//
1532// if not using the NCNR Transmission module, this function default to
1533// returning 0000, and no changes needed
1534Function getXYBoxFromFile(fname,x1,x2,y1,y2)
1535        String fname
1536        Variable &x1,&x2,&y1,&y2
1537       
1538        // return your bounding box coordinates or default values of 0
1539        x1=0
1540        y1=0
1541        x2=0
1542        y2=0
1543
1544        // your code returning value
1545        variable err
1546        string dfName = ""
1547        err = hdfRead(fname, dfName)
1548        //err not handled here
1549
1550        Wave wX1 = $(dfName+":entry1:reduce:x1")
1551        x1 = wX1[0]
1552        Wave wX2 = $(dfName+":entry1:reduce:x2")
1553        x2 = wX2[0]
1554        Wave wY1 = $(dfName+":entry1:reduce:y1")
1555        y1 = wY1[0]
1556        Wave wY2 = $(dfName+":entry1:reduce:y2")
1557        y2 = wY2[0]
1558       
1559        KillWaves wX1, wX2, wY1, wY2
1560        return(0)
1561
1562End
1563
1564// Writes the coordinates of the box to the header after user input
1565//
1566// box to sum over bounded (x1,y1) to (x2,y2)
1567//
1568// if not using the NCNR Transmission module, this function is null
1569Function WriteXYBoxToHeader(fname,x1,x2,y1,y2)
1570        String fname
1571        Variable x1,x2,y1,y2
1572
1573        String groupName = "/entry1/reduce"
1574        variable err
1575       
1576        Wave wX1
1577        Make /N=(1,1) wX1
1578        Wave wX2
1579        Make /N=(1,1) wX2
1580        Wave wY1
1581        Make /N=(1,1) wY1
1582        Wave wY2
1583        Make /N=(1,1) wY2
1584               
1585        wX1[0] = x1
1586        wX2[0] = x2
1587        wY1[0] = y1
1588        wY2[0] = y2     
1589       
1590        String varName = "x1"   
1591        err = hdfWrite(fname, groupName, varName,wX1)
1592        varName = "x2"
1593        err = hdfWrite(fname, groupName, varName,wX2)
1594        varName = "y1"
1595        err = hdfWrite(fname, groupName, varName,wY1)
1596        varName = "y2"
1597        err = hdfWrite(fname, groupName, varName,wY2)   
1598       
1599        KillWaves wX1,wX2,wY1,wY2
1600       
1601        //err not handled here
1602        return(0)       
1603
1604End
1605
1606// for transmission calculation, writes an NCNR-specific alphanumeric identifier
1607// (suffix of the data file)
1608//
1609// if not using the NCNR Transmission module, this function is null
1610Function WriteAssocFileSuffixToHeader(trans_fname,empty_fname)
1611        String trans_fname, empty_fname
1612               
1613// your writer here
1614        Wave/T wEmpty_fname
1615        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1616        Make/T /N=(1,1) wEmpty_fname
1617        String groupName = "/entry1/reduce"
1618        String varName = "empty_beam_file_name"
1619
1620        wEmpty_fname[0] = empty_fname
1621        // your code returning value
1622        variable err
1623        err = hdfWrite(trans_fname, groupName, varName, wEmpty_fname)
1624        KillWaves wEmpty_fname
1625        //err not handled here
1626        return(0)
1627end
1628
1629Function WriteFileAssoc(fname,assoc_fname)
1630        String fname,assoc_fname
1631               
1632// your writer here
1633        Wave/T wAssoc_fname
1634        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1635        Make/T /N=(1,1) wAssoc_fname
1636       
1637        String varName =""
1638        String groupName = "/entry1/reduce"
1639        if(isTransFile(fname))
1640                varName = "empty_beam_file_name"
1641        elseif(isScatFile(fname))
1642                varName = "transmission_file_name"
1643        endif
1644
1645        wAssoc_fname[0] = assoc_fname
1646        // your code returning value
1647        variable err
1648        err = hdfWrite(fname, groupName, varName, wAssoc_fname)
1649        KillWaves wAssoc_fname
1650        //err not handled here
1651        return(0)
1652end
1653
1654Function/S GetFileAssoc(fname)
1655        String fname
1656       
1657        String assoc_fname
1658        String groupName = ":entry1:reduce:"
1659       
1660        String varName = ""
1661        if(isTransFile(fname))
1662                varName = "empty_beam_file_name"
1663        elseif(isScatFile(fname))
1664                varName = "transmission_file_name"
1665        endif
1666       
1667        variable err
1668        string dfName = ""
1669        err = hdfRead(fname, dfName)
1670        //err not handled here
1671
1672        Wave/T wAssoc_fname = $(dfName+groupName+varName)
1673        assoc_fname =wAssoc_fname[0]   
1674        KillWaves wAssoc_fname
1675       
1676        return(assoc_fname)
1677end
1678
1679Function hdfRead(fname, dfName)
1680        //Reads hdf5 file into root:packages:quokka:fname
1681        //N. Hauser. 16/12/08
1682        // 29/1/09 - hdf file must have .nx.hdf or .div suffix
1683       
1684        String fname, &dfName
1685        variable err=0,fileID
1686        String cDF = getDataFolder(1), temp
1687        String fname_temp = ParseFilePath(0, fname, ":", 1, 0)
1688       
1689        String fileSuffix
1690        if(strsearch(fname_temp,".nx.hdf",0,2)>=0)
1691                fileSuffix=".nx.hdf"
1692        //elseif(strsearch(fname_temp,".div",0,2)>=0)
1693        //      fileSuffix=".div"
1694        else
1695                err = 1
1696                abort "unrecognised file suffix. Not .nx.hdf"
1697        endif
1698       
1699        dfName = "root:packages:quokka:"+removeending(fname_temp,fileSuffix)
1700       
1701        //if(!DataFolderExists(dfName))
1702        //      return err
1703        //else         
1704                newDataFolder /O root:packages
1705                newDataFolder /O /S root:packages:quokka
1706                newDataFolder /O /S $dfName
1707        //endif
1708       
1709        try     
1710                HDF5OpenFile /R /Z fileID  as fname
1711                if(!fileID)
1712                        err = 1
1713                        abort "couldn't load HDF5 file"
1714                endif
1715                HDF5LoadGroup /O /R /Z  :, fileID, "."
1716        catch
1717
1718        endtry
1719        if(fileID)
1720                HDF5CloseFile /Z fileID
1721        endif
1722
1723        setDataFolder $cDF
1724        return err
1725end
1726
1727Function hdfWrite(fname, groupName, varName, wav)
1728        //Write Wave 'wav' to hdf5 file 'fname'
1729        //N. Hauser. nha 8/1/09
1730               
1731        String fname, groupName, varName
1732        Wave wav
1733       
1734        variable err=0, fileID,groupID
1735        String cDF = getDataFolder(1), temp
1736        String fname_temp = ParseFilePath(0, fname, ":", 1, 0)
1737       
1738        try     
1739                HDF5OpenFile /Z fileID  as fname  //open file read-write
1740                if(!fileID)
1741                        err = 1
1742                        abort "HDF5 file does not exist"
1743                endif
1744                HDF5OpenGroup /Z fileID , groupName, groupID
1745
1746        //      !! At the moment, there is no entry for sample thickness in our data file
1747        //      therefore create new HDF5 group to enable write / patch command
1748        //      comment out the following group creation once thickness appears in revised file
1749       
1750                if(!groupID)
1751                        HDF5CreateGroup /Z fileID, groupName, groupID
1752                        //err = 1
1753                        //abort "HDF5 group does not exist"
1754                endif           
1755                HDF5SaveData /O /Z  wav, groupID, varName
1756                if (V_flag != 0)
1757                        err = 1
1758                        abort "Cannot save wave to HDF5 group"
1759                endif   
1760        catch
1761
1762        endtry
1763       
1764        if(groupID)
1765                HDF5CloseGroup /Z groupID
1766        endif
1767       
1768        if(fileID)
1769                HDF5CloseFile /Z fileID
1770        endif
1771
1772        setDataFolder $cDF
1773        return err
1774end
1775
1776Function DoEdgeCorrection(type)
1777        String type
1778        variable err = 0
1779       
1780        WAVE typeData=$("root:Packages:NIST:"+type+":data")
1781       
1782        //nha workaround for high counts on edges
1783        //copy second column to first column
1784        typeData[][0] = typeData[p][1]
1785        //copy second last column to last column
1786        typeData[][191] = typeData[p][190]
1787        //copy second row to first row
1788        typeData[0][] = typeData[1][q]
1789        //copy second last row to last row
1790        typeData[191][] = typeData[190][q]
1791       
1792        return err     
1793end
1794
1795////// OCT 2009, facility specific bits from ProDiv()
1796//"type" is the data folder that has the corrected, patched, and normalized DIV data array
1797//
1798// the header of this file is rather unimportant. Filling in a title at least would be helpful/
1799//
1800Function Write_DIV_File(type)
1801        String type
1802       
1803        // Your file writing function here. Don't try to duplicate the VAX binary format...
1804        WriteHeaderAndWork(type)
1805       
1806        return(0)
1807End
1808
1809////// OCT 2009, facility specific bits from MonteCarlo functions()
1810//"type" is the data folder that has the data array that is to be (re)written as a full
1811// data file, as if it was a raw data file
1812//
1813// not really necessary
1814//
1815Function/S Write_RawData_File(type,fullpath,dialog)
1816        String type,fullpath
1817        Variable dialog         //=1 will present dialog for name
1818       
1819        // Your file writing function here. Don't try to duplicate the VAX binary format...
1820        Print "Write_RawData_File stub"
1821       
1822        return(fullpath)
1823End
Note: See TracBrowser for help on using the repository browser.