source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/QKK_ANSTO_DataReadWrite.ipf @ 940

Last change on this file since 940 was 940, checked in by srkline, 9 years ago

Updated the reduction Read/Write? and corresponding factility stubs to accomodate detector dead time written to the VAX header. It is currently not written to the header, but may be with NICE (hopefully).

With the move of NG3 SANS to CGB(upper), the NG3 designation in the account name [NGxSANSxx] has been replaced with CGB. Folders on charlotte and radio button on SASCALC are labeled "NGB30" to be more obvious which instrument it is.

FFT routines have minor typos cleaned up.

File size: 67.6 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion = 6.1 //required to read and write files created with HDF 1.8 library
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]= ParseFilePath(0, fname, ":", 1, 0)   
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        // attenuator number (NCNR-specific, your stub returns 0)
129        // may also be used to hold attenuator transmission (< 1)
130        realw[3] = getAttenNumber(fname)
131       
132        // sample transmission
133        realw[4] = getSampleTrans(fname)
134       
135        //sample thickness (cm)
136        realw[5] = getSampleThickness(fname)
137       
138        // following 6 values are for non-linear spatial corrections to a detector (RC timing)
139        // these values are set for a detctor that has a linear correspondence between
140        // pixel number and real-space distance
141        // 10 and 13 are the X and Y pixel dimensions, respectively (in mm!)
142        //(11,12 and 13,14 are set to values for a linear response, as from a new Ordela detector)
143        realw[10] = getDetectorPixelXSize(fname)
144        realw[11] = 10000
145        realw[12] = 0
146        realw[13] = getDetectorPixelYSize(fname)
147        realw[14] = 10000
148        realw[15] = 0
149       
150        // beam center X,Y on the detector (in units of pixel coordinates (1,N))
151        realw[16] = getBeamXPos(fname)
152        realw[17] = getBeamYPos(fname)
153       
154        // sample to detector distance (meters)
155        realw[18] = getSDD(fname)
156
157        // detector physical width (right now assumes square...) (in cm)
158        //realw[20] = 65
159        realw[20] = getPhysicalWidth(fname)
160       
161        // beam stop diameter (assumes circular) (in mm)
162        realw[21] = getBSDiameter(fname)
163       
164        // source aperture diameter (mm)
165        realw[23] = getSourceApertureDiam(fname)
166       
167        // sample aperture diameter (mm)
168        realw[24] = getSampleApertureDiam(fname)
169       
170        // source aperture to sample aperture distance
171        realw[25] = getSourceToSampleDist(fname)
172       
173        // wavelength (A)
174        realw[26] = getWavelength(fname)
175       
176        // wavelength spread (FWHM)
177        realw[27] = getWavelengthSpread(fname)
178       
179        // beam stop X-position (motor reading, approximate cm from zero position)
180        // currently NCNR-specific use to identify transmission measurements
181        // you return 0
182        realw[37] = 0
183
184// the actual data array, dimensions are set as globals in
185// InitFacilityGlobals()
186        NVAR XPix = root:myGlobals:gNPixelsX
187        NVAR YPix = root:myGlobals:gNPixelsX
188       
189        Make/D/O/N=(XPix,YPix) $"root:Packages:NIST:RAW:data"
190        WAVE data=$"root:Packages:NIST:RAW:data"
191
192        // fill the data array with the detector values
193        getDetectorData(fname,data)
194       
195        // total detector count
196        //nha 21/5/10 moved here because it requires the detector data to already be written
197        //Result of issue with 0 counts being written for a while in metadata.
198        realw[2] = getDetCount(fname)
199       
200        //keep a string with the filename in the RAW folder
201        String/G root:Packages:NIST:RAW:fileList = textw[0]
202       
203        Return 0
204
205End
206
207//****************
208//main entry procedure for reading a "WORK.DIV" file
209//displays a quick image of the  file, to check that it's correct
210//data is deposited in root:Packages:NIST:DIV data folder
211//
212// local, just for testing
213//
214Proc ReadWork_DIV()
215       
216        String fname = PromptForPath("Select detector sensitivity file")
217        ReadHeaderAndWork("DIV",fname)          //puts what is read in work.div
218       
219        String waveStr = "root:Packages:NIST:DIV:data"
220        NewImage/F/K=1/S=2 $waveStr
221        ModifyImage '' ctab= {*,*,YellowHot,0}
222       
223        String/G root:Packages:NIST:DIV:fileList = "WORK.DIV"
224       
225        SetDataFolder root:             //(redundant)
226End
227
228
229
230// Detector sensitivity files have the same header structure as RAW SANS data
231// as NCNR, just with a different data array (real, rather than integer data)
232//
233// So for your facility, make this reader specific to the format of whatever
234// file you use for a pixel-by-pixel division of the raw detector data
235// to correct for non-uniform sensitivities of the detector. This is typically a
236// measurement of water, plexiglas, or another uniform scattering sample.
237//
238// The data must be normalized to a mean value of 1
239//
240// called from ProtocolAsPanel.ipf
241//
242// type is "DIV" on input
243Function ReadHeaderAndWork(type,fname)
244        String type,fname
245       
246        //type is the desired folder to read the workfile to
247        //this data will NOT be automatically displayed
248        // gDataDisplayType is unchanged
249
250        String cur_folder = type
251        String curPath = "root:Packages:NIST:"+cur_folder
252        SetDataFolder curPath           //use the full path, so it will always work
253       
254        Variable refNum,integer,realval
255        String sansfname,textstr
256        Variable/G $(curPath + ":gIsLogScale") = 0              //initial state is linear, keep this in DIV folder
257       
258        Make/O/D/N=23 $(curPath + ":IntegersRead")
259        Make/O/D/N=52 $(curPath + ":RealsRead")
260        Make/O/T/N=11 $(curPath + ":TextRead")
261       
262        WAVE intw=$(curPath + ":IntegersRead")
263        WAVE realw=$(curPath + ":RealsRead")
264        WAVE/T textw=$(curPath + ":TextRead")
265       
266        // the actual data array, dimensions are set as globals in
267        // InitFacilityGlobals()
268        NVAR XPix = root:myGlobals:gNPixelsX
269        NVAR YPix = root:myGlobals:gNPixelsX
270
271        Make/O/D/N=(XPix,YPix) $(curPath + ":data")
272        WAVE data = $(curPath + ":data")
273       
274        // (1)
275        // fill in your reader for the header here so that intw, realw, and textW are filled in
276        // ? possibly a duplication of the raw data reader
277               
278        //(2)
279        // then fill in a reader for the data array that will DIVIDE your data
280        // to get the corrected values.
281        String dfName=""
282        variable err
283        err = hdfRead(fname, dfName)
284       
285        // [davidm]
286        if (exists(dfName+":reduce:div"))
287                Wave tempData = $dfName+":reduce:div"
288        else
289                Wave tempData = $dfName+":data:div"
290        endif
291
292        data = tempData
293       
294        //funky edge correction bodgy ???
295        //copy second column to first column
296        data[][0] = data[p][1]
297        //copy second last column to last column
298        data[][191] = data[p][190]
299        //copy second row to first row
300        data[0][] = data[1][q]
301        //copy second last row to last row
302        data[191][] = data[190][q]
303        //keep a string with the filename in the DIV folder
304        String/G $(curPath + ":fileList") = textw[0]
305       
306        //return the data folder to root
307        SetDataFolder root:
308       
309        Return(0)
310End
311
312Function WriteHeaderAndWork(type)
313        String type
314       
315        // your writer here
316        NVAR XPix = root:myGlobals:gNPixelsX
317        NVAR YPix = root:myGlobals:gNPixelsX   
318       
319        Wave wData=$("root:Packages:NIST:"+type+":data")
320       
321//      Variable refnum,ii=0,hdrBytes=516,a,b,offset
322        String fname=""
323//      Duplicate/O wData,tempData
324       
325        //changed for Quokka
326//      Redimension/S/N=(XPix*YPix) tempData
327//      tempData *= 4
328       
329        PathInfo/S catPathName
330        fname = DoSaveFileDialog("Save data as")          //won't actually open the file
331        If(cmpstr(fname,"")==0)
332                //user cancel, don't write out a file
333          Close/A
334          Abort "no data file was written"
335        Endif
336       
337        variable fileID
338        HDF5CreateFile /O fileID as fname
339       
340        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
341        //Make /N=(1,1) wTransmission
342        String groupName = "/reduce"
343        String varName = "div"
344        // your code returning value
345        variable err
346        err = hdfWrite(fname, groupName, varName, wData)
347
348        // KillWaves wData, tempData
349        return(0)
350End
351
352
353
354/////   ASC FORMAT READER  //////
355/////   FOR WORKFILE MATH PANEL //////
356//
357//function to read in the ASC output of SANS reduction
358// currently the file has 20 header lines, followed by a single column
359// of 16384 values, Data is written by row, starting with Y=1 and X=(1->128)
360//
361//returns 0 if read was ok
362//returns 1 if there was an error
363//
364// called by WorkFileUtils.ipf
365//
366//
367// If the ASC data was generated by the NCNR data writer, then
368// NOTHING NEEDS TO BE CHANGED HERE
369//
370Function ReadASCData(fname,destPath)
371        String fname, destPath
372        //this function is for reading in ASCII data so put data in user-specified folder
373        SetDataFolder "root:Packages:NIST:"+destPath
374
375        NVAR pixelsX = root:myGlobals:gNPixelsX
376        NVAR pixelsY = root:myGlobals:gNPixelsY
377        Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20
378        String str=""
379        //data is initially linear scale
380        Variable/G :gIsLogScale=0
381        Make/O/T/N=(numHdrLines) hdrLines
382        Make/O/D/N=(pixelsX*pixelsY) data                       //,linear_data
383       
384        //full filename and path is now passed in...
385        //actually open the file
386//      SetDataFolder destPath
387        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
388        if(refnum==0)           //FNF error, get out
389                DoAlert 0,"Could not find file: "+fname
390                Close/A
391                SetDataFolder root:
392                return(1)
393        endif
394        if(V_flag!=0)
395                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
396                Close/A
397                SetDataFolder root:
398                return(1)
399        Endif
400        //
401        for(ii=0;ii<numHdrLines;ii+=1)          //read (or skip) 18 header lines
402                FReadLine refnum,str
403                hdrLines[ii]=str
404        endfor
405        //     
406        Close refnum
407       
408//      SetDataFolder destPath
409        LoadWave/Q/G/D/N=temp fName
410        Wave/Z temp0=temp0
411        data=temp0
412        Redimension/N=(pixelsX,pixelsY) data            //,linear_data
413       
414        //linear_data = data
415       
416        KillWaves/Z temp0
417       
418        //return the data folder to root
419        SetDataFolder root:
420       
421        Return(0)
422End
423
424// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
425// pay attention to what is/not to be trusted due to "fake" information.
426// uses what it can from the header lines from the ASC file (hdrLines wave)
427//
428// destFolder is of the form "myGlobals:WorkMath:AAA"
429//
430//
431// called by WorkFileUtils.ipf
432//
433// If the ASC data was generated by the NCNR data writer, then
434// NOTHING NEEDS TO BE CHANGED HERE
435//
436Function FillFakeHeader_ASC(destFolder)
437        String destFolder
438        Make/O/D/N=23 $("root:Packages:NIST:"+destFolder+":IntegersRead")
439        Make/O/D/N=52 $("root:Packages:NIST:"+destFolder+":RealsRead")
440        Make/O/T/N=11 $("root:Packages:NIST:"+destFolder+":TextRead")
441       
442        Wave intw=$("root:Packages:NIST:"+destFolder+":IntegersRead")
443        Wave realw=$("root:Packages:NIST:"+destFolder+":RealsRead")
444        Wave/T textw=$("root:Packages:NIST:"+destFolder+":TextRead")
445       
446        //Put in appropriate "fake" values
447        //parse values as needed from headerLines
448        Wave/T hdr=$("root:Packages:NIST:"+destFolder+":hdrLines")
449        Variable monCt,lam,offset,sdd,trans,thick
450        Variable xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam
451        String detTyp=""
452        String tempStr="",formatStr="",junkStr=""
453        formatStr = "%g %g %g %g %g %g"
454        tempStr=hdr[3]
455        sscanf tempStr, formatStr, monCt,lam,offset,sdd,trans,thick
456//      Print monCt,lam,offset,sdd,trans,thick,avStr,step
457        formatStr = "%g %g %g %g %g %g %g %s"
458        tempStr=hdr[5]
459        sscanf tempStr,formatStr,xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
460//      Print xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
461       
462        realw[16]=xCtr          //xCtr(pixels)
463        realw[17]=yCtr  //yCtr (pixels)
464        realw[18]=sdd           //SDD (m)
465        realw[26]=lam           //wavelength (A)
466        //
467        // necessary values
468        realw[10]=5                     //detector calibration constants, needed for averaging
469        realw[11]=10000
470        realw[12]=0
471        realw[13]=5
472        realw[14]=10000
473        realw[15]=0
474        //
475        // used in the resolution calculation, ONLY here to keep the routine from crashing
476        realw[20]=65            //det size
477        realw[27]=dlam  //delta lambda
478        realw[21]=bsDiam        //BS size
479        realw[23]=a1            //A1
480        realw[24]=a2    //A2
481        realw[25]=a1a2Dist      //A1A2 distance
482        realw[4]=trans          //trans
483        realw[3]=0              //atten
484        realw[5]=thick          //thick
485        //
486        //
487        realw[0]=monCt          //def mon cts
488
489        // fake values to get valid deadtime and detector constants
490        //
491        textw[9]=detTyp+"  "            //6 characters 4+2 spaces
492        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
493       
494        //set the string values
495        formatStr="FILE: %s CREATED: %s"
496        sscanf hdr[0],formatStr,tempStr,junkStr
497//      Print tempStr
498//      Print junkStr
499        String/G $("root:Packages:NIST:"+destFolder+":fileList") = tempStr
500        textw[0] = tempStr              //filename
501        textw[1] = junkStr              //run date-time
502       
503        //file label = hdr[1]
504        tempStr = hdr[1]
505        tempStr = tempStr[0,strlen(tempStr)-2]          //clean off the last LF
506//      Print tempStr
507        textW[6] = tempStr      //sample label
508       
509        return(0)
510End
511
512
513///////// ACCESSORS FOR WRITING DATA TO HEADER  /////////
514/////
515
516// Write* routines all must:
517// (1) open file "fname". fname is a full file path and name to the file on disk
518// (2) write the specified value to the header at the correct location in the file
519// (3) close the file
520
521
522
523//whole transmission is NCNR-specific right now
524// leave this stub empty
525Function WriteWholeTransToHeader(fname,wholeTrans)
526        String fname
527        Variable wholeTrans
528       
529        String groupName = "/reduce"
530        variable err
531       
532        Wave wCounts
533        Make /N=(1,1) wWholeTrans
534               
535        wWholeTrans[0] = wholeTrans
536       
537        String varName = "wholeTransmission"   
538        err = hdfWrite(fname, groupName, varName,wWholeTrans)
539
540        KillWaves wWholeTrans
541       
542        //err not handled here
543        return(0)       
544End
545
546//box sum counts is a real value
547// used for transmission calculation module
548Function WriteBoxCountsToHeader(fname,counts)
549        String fname
550        Variable counts
551       
552        // do nothing if not using NCNR Transmission module
553       
554        String groupName = "/reduce"
555        variable err
556       
557        Wave wCounts
558        Make /N=(1,1) wCounts
559               
560        wCounts[0] = counts
561       
562        String varName = "boxCounts"   
563        err = hdfWrite(fname, groupName, varName,wCounts)
564
565        KillWaves wCounts
566       
567        //err not handled here
568        return(0)       
569End
570
571//beam stop X-position
572// used for transmission module to manually tag transmission files
573Function WriteBSXPosToHeader(fname,xpos)
574        String fname
575        Variable xpos
576       
577        // do nothing if not using NCNR Transmission module
578        //print "not implemented: WriteBSXPosToHeader"
579       
580        return(0)
581End
582
583
584
585
586
587//attenuator number (not its transmission)
588// if your beam attenuation is indexed in some way, use that number here
589// if not, write a 1 to the file here as a default
590//
591Function WriteAttenNumberToHeader(fname,attenNumber)
592        String fname
593        Variable attenNumber
594       
595        // your writer here
596        Wave wAttenNumber
597        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
598        Make /N=(1,1) wAttenNumber
599        String groupName = "/instrument/collimator"
600        String varName = "att"
601        //convert number to a rotation angle
602        attenNumber = attenNumber * 30
603        wAttenNumber[0] = attenNumber //
604        // your code returning value
605        variable err
606        err = hdfWrite(fname, groupName, varName, wAttenNumber)
607        KillWaves wAttenNumber
608        //err not handled here
609               
610        return(0)
611
612End
613
614
615// total monitor count during data collection
616Function WriteMonitorCountToHeader(fname,num)
617        String fname
618        Variable num
619       
620        // your code here
621        //print "not implemented: WriteMonitorCountToHeader"
622       
623        return(0)
624End
625
626//total detector count
627Function WriteDetectorCountToHeader(fname,num)
628        String fname
629        Variable num
630       
631        // your code here
632        //print "not implemented: WriteDetectorCountToHeader"
633       
634        return(0)
635End
636
637//transmission detector count
638// (currently unused in data reduction)
639Function WriteTransDetCountToHeader(fname,num)
640        String fname
641        Variable num
642       
643        // do nothing for now
644        //print "not implemented: WriteTransDetCountToHeader"
645       
646        return(0)
647End
648
649
650
651//temperature of the sample (C)
652Function WriteTemperatureToHeader(fname,num)
653        String fname
654        Variable num
655       
656        //  your code here
657        //print "not implemented: WriteTemperatureToHeader"
658       
659        return(0)
660End
661
662//magnetic field (Oe)
663Function WriteMagnFieldToHeader(fname,num)
664        String fname
665        Variable num
666       
667        // your code here
668        //print "not implemented: WriteMagnFieldToHeader"
669       
670        return(0)
671End
672
673//lateral detector offset (centimeters)
674Function WriteDetectorOffsetToHeader(fname,DetectorOffset)
675        String fname
676        Variable DetectorOffset
677       
678        // your writer here
679        Wave wDetectorOffset
680        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
681        Make /N=(1,1) wDetectorOffset
682        String groupName = "/instrument/detector"
683        String varName = "detector_x"
684        //convert from cm (NIST standard) to mm (NeXus standard)
685        DetectorOffset = DetectorOffset * 10
686        wDetectorOffset[0] = DetectorOffset //
687        // your code returning value
688        variable err
689        err = hdfWrite(fname, groupName, varName, wDetectorOffset)
690        KillWaves wDetectorOffset
691        //err not handled here
692       
693        return(0)
694End
695
696
697
698
699// physical dimension of detector x-pixel (mm)
700Function WriteDetPixelXToHeader(fname,num)
701        String fname
702        Variable num
703       
704        //your code here
705        //print "not implemented: WriteDetPixelXToHeader"
706       
707        return(0)
708end
709
710// physical dimension of detector y-pixel (mm)
711Function WriteDetPixelYToHeader(fname,num)
712        String fname
713        Variable num
714       
715        //your code here
716        //print "not implemented: WriteDetPixelYToHeader"
717       
718        return(0)
719end
720
721// sample label string
722Function WriteSamLabelToHeader(fname,str)
723        String fname,str
724       
725        String groupName = "/sample"
726        //String varName = "name"
727
728        //your code here
729        //print "not implemented: WriteSamLabelToHeader"
730
731        return(0)
732End
733
734// total counting time (seconds)
735Function WriteCountTimeToHeader(fname,num)
736        String fname
737        Variable num
738       
739        // your code here
740        //print "not implemented: WriteCountTimeToHeader"
741       
742        return(0)
743End
744
745
746
747//////// ACCESSORS FOR READING DATA FROM THE HEADER  //////////////
748//
749// read specific bits of information from the header
750// each of these operations MUST take care of open/close on their own
751//
752// fname is the full path and filname to the file on disk
753// return values are either strings or real values as appropriate
754//
755//////
756
757
758// function that reads in the 2D detector data and fills the array
759// data[nx][ny] with the data values
760// fname is the full name and path to the data file for opening and closing
761//
762//
763Function getDetectorData(fname,data)
764        String fname
765        Wave data
766        NVAR XPix = root:myGlobals:gNPixelsX
767       
768        // your reader here
769        variable err
770        string dfName = ""
771        err = hdfRead(fname, dfName)
772        if(err)
773                return 0
774        endif
775
776        Wave hmm_xy = $(dfName+":data:hmm_xy")
777       
778        //redimension /I /N = (dimsize(hmm_xy, 2), dimsize(hmm_xy, 1)), data
779        //nha. Count arrays need to be floating point, since the data will be divided, normalised etc.
780        redimension /N = (dimsize(hmm_xy, 2), dimsize(hmm_xy, 1)), data
781        data[][] = hmm_xy[0][q][p]
782       
783        //nha workaround. for wrongly dimensioned Quokka data 191x192
784        variable x_dim = dimsize(data,0)
785        if (x_dim!=XPix)
786                //redimension to add an extra row(s) to the data
787                redimension /I /N = (XPix,-1) data
788                //copy row 190 to row 191
789                data[191][] = data[190][q]
790        endif   
791        // end workaround
792       
793        //funky edge correction bodgy ???
794        //copy second column to first column
795        data[][0] = data[p][1]
796        //copy second last column to last column
797        data[][191] = data[p][190]
798        //copy second row to first row
799        data[0][] = data[1][q]
800        //copy second last row to last row
801        data[191][] = data[190][q]
802                       
803        KillWaves hmm_xy
804       
805       
806        return(0)
807End
808
809// file suffix (NCNR data file name specific)
810// return filename as suffix
811Function/S getSuffix(fname)
812        String fname
813       
814        return(ParseFilePath(0, fname, ":", 1, 0))
815End
816
817// associated file suffix (for transmission)
818// NCNR Transmission calculation specific
819// return null string
820Function/S getAssociatedFileSuffix(fname)
821        String fname
822       
823        return(getFileAssoc(fname))
824End
825
826// sample label
827Function/S getSampleLabel(fname)
828        String fname
829        String str
830       
831        string dfName = ""
832        hdfReadSimulated(fname, dfName)
833       
834        if (exists(dfName+":sample:name") != 1)
835                // your code, returning str
836                variable err
837                err = hdfRead(fname, dfName)
838                //err not handled here
839        endif
840       
841        Wave/T wSampleName = $dfname+":sample:name"
842       
843        if (waveexists(wSampleName))
844                str = wSampleName[0]
845        else
846                print "Can't find Sample Label in " + fname
847                str = ""
848        endif
849       
850        //KillWaves wSampleName
851       
852
853//      // your code, returning str
854//      variable err
855//      string dfName = ""
856//      err = hdfRead(fname, dfName)
857//      //err not handled here
858//     
859//      Wave/T wSampleName = $dfname+":sample:name"
860//      str = wSampleName[0]
861//      KillWaves wSampleName
862       
863        return(str)
864End
865
866// file creation date
867Function/S getFileCreationDate(fname)
868        String fname
869        String str
870       
871        string dfName = ""
872        hdfReadSimulated(fname, dfName)
873       
874        if (exists(dfName+":start_time") != 1)
875                // your code, returning str
876                variable err
877                err = hdfRead(fname, dfName)
878                //err not handled here
879        endif
880       
881        Wave/T wStartTime = $dfName+":start_time"
882       
883        if (WaveExists(wStartTime))
884                str = wStartTime[0]
885        else
886                print "Can't find File Creation Date in " + fname
887                str = ""
888        endif
889       
890        //KillWaves wSampleName
891       
892//      // your code, returning str
893//      variable err
894//      string dfName = ""
895//      err = hdfRead(fname, dfName)
896//      //err not handled here
897//     
898//      Wave/T wStartTime = $dfName+":start_time"
899//      str = wStartTime[0]
900//      KillWaves wStartTime
901       
902        return(str)
903End
904
905
906//monitor count
907Function getMonitorCount(fname)
908        String fname
909        Variable value
910        Variable att, err
911        string dfName = ""
912               
913        //err = hdfRead(fname, dfName)
914        //err not handled here
915       
916        // [davidm]
917        hdfReadSimulated(fname, dfName)
918       
919        if(!WaveExists($(dfName+":monitor:bm1_counts")))
920                err = hdfRead(fname, dfName)
921                //err not handled here
922        endif
923
924        Wave wMonCnts = $(dfName+":monitor:bm1_counts")
925        if(WaveExists(wMonCnts))
926                value = wMonCnts[0]
927        else
928                print "Can't find Monitor Count in " + fname
929        endif   
930
931        // davidm
932        if (value == 0)
933                print "***monitor count is ZERO*** and has been reset to 1.0"
934                value = 1
935        endif
936       
937        // [davidm]
938        //KillWaves wAttrotdeg
939        return(value)
940end
941
942//saved monitor count
943// NCNR specific for pre-processed data, never used
944// return 0
945Function getSavMon(fname)
946        String fname
947       
948        Variable value
949       
950        // your code returning value
951        //??? to do. Is this required if 'never used'? nha
952       
953        return(0)
954end
955
956//total detector count
957Function getDetCount(fname)
958//not patched, but could be
959        String fname
960        Variable value
961       
962//      // your code returning value
963//      variable err
964//      string dfName = ""
965//      err = hdfRead(fname, dfName)
966        //err not handled here
967       
968        // [davidm]
969        string dfName = ""
970        hdfReadSimulated(fname, dfName)
971       
972        if(!WaveExists($(dfName+":data:total_counts")) && !WaveExists($(dfName+":instrument:detector:total_counts")))
973                // your code, returning str
974                variable err
975                err = hdfRead(fname, dfName)
976                //err not handled here
977        endif
978
979        //      Wave wCounts = $(dfName+":data:total_counts")
980        // changed 22/12/09 nha
981        if(WaveExists($(dfName+":data:total_counts")))
982                Wave wCounts = $(dfName+":data:total_counts")
983                value = wCounts[0]
984        elseif(WaveExists($(dfName+":instrument:detector:total_counts")))
985        Wave wCounts = $(dfName+":instrument:detector:total_counts")
986                value = wCounts[0]
987       else
988        print "Can't find Total Detector Count in " + fname
989       endif
990
991        // davidm
992        if (value < 1)
993                print "Warning: Total Detector Count smaller than 1!"
994        endif
995       
996        //nha 21/5/10 temporary glitch wrote detector count to file as 0       
997//              if (value<1)
998//                      NVAR XPix = root:myGlobals:gNPixelsX
999//                      NVAR YPix = root:myGlobals:gNPixelsX
1000//                      Make/D/O/N=(XPix,YPix) $"root:RAW:data"
1001//                      WAVE data=$"root:RAW:data"
1002//                      getDetectorData(fname,data)
1003//                      value = sum(data)
1004//              endif
1005       
1006        // davidm
1007        if (value == 0)
1008                print "***total detector count is ZERO*** and has been reset to 1.0"
1009                value = 1
1010        endif
1011       
1012        // [davidm]
1013        //KillWaves wCounts
1014       
1015        return(value)
1016end
1017
1018//Attenuator number, return 1 if your attenuators are not
1019// indexed by number
1020Function getAttenNumber(fname)
1021        String fname
1022        Variable value
1023        Variable att, err
1024        string dfName = ""
1025               
1026        //err = hdfRead(fname, dfName)
1027        //err not handled here
1028       
1029        // [davidm]
1030        hdfReadSimulated(fname, dfName)
1031       
1032        if(!WaveExists($(dfName+":instrument:collimator:att")) && !WaveExists($(dfName+":instrument:parameters:derived_parameters:AttRotDeg")))
1033                err = hdfRead(fname, dfName)
1034                //err not handled here
1035        endif
1036
1037        if(WaveExists($(dfName+":instrument:collimator:att")))
1038                Wave wAttrotdeg = $(dfName+":instrument:collimator:att")
1039                value = wAttrotdeg[0]
1040        elseif(WaveExists($(dfName+":instrument:parameters:derived_parameters:AttRotDeg")))
1041                Wave wAttrotdeg = $(dfName+":instrument:parameters:derived_parameters:AttRotDeg")
1042                value = wAttrotdeg[0]
1043        else
1044                print "Can't find Attenuator in " + fname
1045        endif   
1046       
1047        att = round(value)/30
1048       
1049        // [davidm]
1050        //KillWaves wAttrotdeg
1051        return(att)
1052end
1053
1054
1055//transmission
1056Function getSampleTrans(fname)
1057        String fname
1058       
1059        Variable value
1060       
1061        // your code returning value
1062        variable err
1063        string dfName = ""
1064       
1065        //err = hdfRead(fname, dfName)
1066        //err not handled here
1067       
1068        // [davidm]
1069        hdfReadSimulated(fname, dfName)
1070       
1071        if(!WaveExists($(dfName+":reduce:Transmission")) && !WaveExists($(dfName+":instrument:parameters:Transmission")))
1072                err = hdfRead(fname, dfName)
1073                //err not handled here
1074        endif
1075
1076        if(WaveExists($(dfName+":reduce:Transmission"))) //canonical location
1077                Wave wTransmission = $(dfName+":reduce:Transmission")
1078                value = wTransmission[0]
1079        elseif(WaveExists($(dfName+":instrument:parameters:Transmission")))
1080                Wave wTransmission = $(dfName+":instrument:parameters:Transmission")
1081                value = wTransmission[0]
1082        else
1083                print "Can't find Transmission in " + fname
1084        endif
1085       
1086        // [davidm]
1087        //KillWaves wTransmission
1088               
1089        return(value)
1090end
1091
1092//sample transmission (0<T<=1)
1093Function WriteTransmissionToHeader(fname,trans)
1094        String fname
1095        Variable trans
1096       
1097        // your writer here
1098        Wave wTransmission
1099        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1100        Make /N=(1,1) wTransmission
1101        String groupName = "/instrument/parameters"
1102        String varName = "Transmission"
1103        wTransmission[0] = trans //
1104        // your code returning value
1105        variable err
1106        err = hdfWrite(fname, groupName, varName, wTransmission)
1107        KillWaves wTransmission
1108        //err not handled here
1109               
1110        return(0)
1111End
1112
1113//box counts from stored transmission calculation
1114// return 0 if not using NCNR transmission module
1115Function getBoxCounts(fname)
1116        String fname
1117        Variable value
1118       
1119        // do nothing if not using NCNR Transmission module
1120        variable err
1121        string dfName = ""
1122        err = hdfRead(fname, dfName)
1123        //err not handled here
1124
1125        Wave wBoxCounts = $(dfName+":reduce:boxCounts")
1126        if (waveexists(wBoxCounts) == 0)
1127                //boxcounts not yet set in  reduce group
1128                print "No box counts in " + fname + ":reduce:boxCounts"
1129                value = 0
1130        else
1131                value = wBoxCounts[0]
1132        endif
1133
1134        KillWaves/Z wBoxCounts
1135       
1136        return(value)
1137end
1138
1139//whole detector transmission
1140// return 0 if not using NCNR transmission module
1141Function getSampleTransWholeDetector(fname)
1142        String fname
1143        Variable value
1144       
1145        //print "not implemented: getSampleTransWholeDetector"
1146       
1147        // your code returning value
1148        // ??? don't know what to put here. nha
1149        value=0
1150        return(value)
1151end
1152
1153//SampleThickness in centimeters
1154Function getSampleThickness(fname)
1155        String fname
1156        Variable value
1157
1158        // your code returning value
1159       
1160        variable err
1161        string dfName = ""
1162       
1163        // [davidm]
1164        hdfReadSimulated(fname, dfName)
1165       
1166        variable flag = 0
1167        if(WaveExists($(dfName+":sample:SampleThickness"))) //canonical location - a bit ugly and verbose, but that's just my opinion
1168                flag = 1
1169        elseif(WaveExists($(dfName+":sample:thickness")))
1170                flag = 1
1171        endif
1172       
1173        if (flag == 0)
1174                err = hdfRead(fname, dfName)
1175                //err not handled here
1176        endif
1177
1178        if(WaveExists($(dfName+":sample:SampleThickness"))) //canonical location - a bit ugly and verbose, but that's just my opinion
1179                Wave wThickness = $(dfName+":sample:SampleThickness")
1180                value = wThickness[0]/10
1181        elseif(WaveExists($(dfName+":sample:thickness")))
1182                Wave wThickness = $(dfName+":sample:thickness")
1183                value = wThickness[0]/10
1184        else
1185                print "Can't find Sample Thickness in " + fname
1186        endif
1187                       
1188        //value = 1 //??? temporary fix. nha
1189        // [davidm]
1190        //KillWaves wThickness
1191       
1192        return(value)
1193end
1194
1195//sample thickness in cm
1196Function WriteThicknessToHeader(fname,thickness)
1197        String fname
1198        Variable thickness
1199       
1200        // your writer here
1201        Wave wThickness
1202        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1203        Make /N=(1,1) wThickness
1204        String groupName = "/sample"
1205        String varName = "SampleThickness"
1206        wThickness[0] = thickness*10 //
1207        // your code returning value
1208        variable err
1209        err = hdfWrite(fname, groupName, varName, wThickness) //does not exist ???
1210        KillWaves wThickness
1211        //err not handled here
1212               
1213        return(0)
1214End
1215
1216//Sample Rotation Angle (degrees)
1217Function getSampleRotationAngle(fname)
1218        String fname
1219        Variable value
1220       
1221        // your code returning value
1222        variable err
1223        string dfName = ""
1224       
1225        // [davidm]
1226        hdfReadSimulated(fname, dfName)
1227        if (exists(dfName+":sample:sample_theta") != 1)
1228                err = hdfRead(fname, dfName)
1229                //err not handled here
1230        endif
1231
1232        Wave wSample_rotation_angle = $(dfName+":sample:sample_theta") //is this correct
1233        if (WaveExists(wSample_rotation_angle))
1234                value = wSample_rotation_angle[0]
1235        else
1236                print "Can't find Sample Rotation Angle in " + fname
1237        endif
1238       
1239        // [davidm]
1240        //KillWaves wSample_rotation_angle
1241               
1242        return(value)
1243end
1244
1245//temperature (C)
1246Function getTemperature(fname)
1247        String fname
1248        Variable value
1249       
1250        // your code returning value
1251        variable err
1252        string dfName = ""
1253       
1254        // [davidm]
1255        hdfReadSimulated(fname, dfName)
1256        if (exists(dfName+":sample:tc1:sensor:value") != 1)
1257                err = hdfRead(fname, dfName)
1258                //err not handled here
1259        endif
1260
1261        Wave wSample_tc1_value = $(dfName+":sample:tc1:sensor:value")
1262        if (WaveExists(wSample_tc1_value))
1263                value = wSample_tc1_value[0]
1264        else
1265                print "Can't find Sample Rotation Angle in " + fname
1266        endif
1267       
1268        // [davidm]
1269        //KillWaves wSample_tc1_value
1270       
1271        return(value)
1272end
1273
1274//field strength (Oe)
1275Function getFieldStrength(fname)
1276        String fname
1277       
1278        Variable value
1279       
1280        // your code returning value
1281        //print "not implemented: getFieldStrength"
1282       
1283        return(value)
1284end
1285
1286//center of beam xPos in pixel coordinates
1287Function getBeamXPos(fname)
1288        String fname
1289        Variable value
1290        // your code returning value
1291        variable err
1292        string dfName = ""
1293       
1294        // [davidm]
1295        hdfReadSimulated(fname, dfName)
1296       
1297        variable flag = 0       
1298        if(WaveExists($(dfName+":instrument:parameters:BeamCenterX"))) //canonical location
1299                flag = 1
1300        elseif(WaveExists($(dfName+":instrument:reduce:BeamCenterX")))
1301                flag = 1
1302        endif
1303       
1304        if (flag == 0)
1305                err = hdfRead(fname, dfName)
1306                //err not handled here
1307        endif
1308       
1309        if(WaveExists($(dfName+":instrument:parameters:BeamCenterX"))) //canonical location
1310                Wave wBeamXPos = $(dfName+":instrument:parameters:BeamCenterX")
1311                value = wBeamXPos[0]
1312        elseif(WaveExists($(dfName+":instrument:reduce:BeamCenterX"))) // check if its an old file
1313                Wave wBeamXPos = $(dfName+":instrument:reduce:BeamCenterX")
1314                value = wBeamXPos[0]
1315        else
1316                print "Can't find BeamCenterX in" + fname
1317        endif
1318
1319        // if BeamCenterX was not found then wBeamXPos doesn't exist [dmaennic]
1320        // value = wBeamXPos[0]
1321        // KillWaves wBeamXPos
1322               
1323        return(value)   
1324end
1325
1326//beam center X pixel location (detector coordinates)
1327Function WriteBeamCenterXToHeader(fname,beamCenterX)
1328        String fname
1329        Variable beamCenterX
1330       
1331        // your writer here
1332        Wave wBeamCenterX
1333        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1334        Make /N=(1,1) wBeamCenterX
1335        String groupName = "/instrument/parameters"
1336        String varName = "BeamCenterX"
1337        wBeamCenterX[0] = beamCenterX //
1338        // your code returning value
1339        variable err
1340        err = hdfWrite(fname, groupName, varName, wBeamCenterX)
1341        KillWaves wBeamCenterX
1342        //err not handled here
1343       
1344        return(0)
1345End
1346
1347//center of beam Y pos in pixel coordinates
1348Function getBeamYPos(fname)
1349        String fname
1350        Variable value
1351        // your code returning value
1352        variable err
1353        string dfName = ""
1354
1355        // [davidm]
1356        hdfReadSimulated(fname, dfName)
1357       
1358        variable flag = 0       
1359        if(WaveExists($(dfName+":instrument:parameters:BeamCenterZ"))) //canonical location
1360                flag = 1
1361        elseif(WaveExists($(dfName+":instrument:reduce:BeamCenterZ")))
1362                flag = 1
1363        endif
1364       
1365        if (flag == 0)
1366                err = hdfRead(fname, dfName)
1367                //err not handled here
1368        endif
1369
1370        if(WaveExists($(dfName+":instrument:parameters:BeamCenterZ"))) //canonical location
1371                Wave wBeamYPos = $(dfName+":instrument:parameters:BeamCenterZ")
1372                value = wBeamYPos[0]                   
1373        elseif(WaveExists($(dfName+":instrument:reduce:BeamCenterZ")))
1374                Wave wBeamYPos = $(dfName+":instrument:reduce:BeamCenterZ")
1375                value = wBeamYPos[0]
1376        else
1377                print "Can't find BeamCenterZ in" + fname
1378        endif
1379               
1380        // if BeamCenterY was not found then wBeamYPos doesn't exist [dmaennic]
1381        // value = wBeamYPos[0]
1382        // KillWaves wBeamYPos
1383               
1384        return(value)
1385end
1386
1387//beam center Y pixel location (detector coordinates)
1388Function WriteBeamCenterYToHeader(fname,beamCenterY)
1389        String fname
1390        Variable beamCenterY
1391       
1392        // your writer here
1393        Wave wBeamCenterY
1394        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1395        Make /N=(1,1) wBeamCenterY
1396        String groupName = "/instrument/parameters"
1397        String varName = "BeamCenterZ"
1398        wBeamCenterY[0] = beamCenterY //
1399        // your code returning value
1400        variable err
1401        err = hdfWrite(fname, groupName, varName, wBeamCenterY)
1402        KillWaves wBeamCenterY
1403        //err not handled here
1404
1405        return(0)
1406End
1407
1408//sample to detector distance (meters)
1409Function getSSD(fname) // added by [davidm]
1410        String fname
1411        Variable value
1412        // your code returning value
1413        variable err
1414        string dfName = ""
1415       
1416        // [davidm]
1417        //err = hdfRead(fname, dfName)
1418        //err not handled here
1419
1420        hdfReadSimulated(fname, dfName)
1421       
1422        variable flag = 0
1423        if(WaveExists($(dfName+":instrument:parameters:L1"))) //canonical location
1424                flag = 1
1425        elseif(WaveExists($(dfName+":instrument:parameters:L1mm")))
1426                flag = 1
1427        elseif(WaveExists($(dfName+":instrument:parameters:derived_parameters:L1mm")))
1428                flag = 1
1429        endif
1430       
1431        if(flag == 0)
1432                err = hdfRead(fname, dfName)
1433                //err not handled here
1434        endif
1435
1436        //workaround for bad HDF5 dataset
1437        if(WaveExists($(dfName+":instrument:parameters:L1"))) //canonical location
1438                Wave wSampleToSourceDist = $(dfName+":instrument:parameters:L1")
1439                value = wSampleToSourceDist[0]/1000
1440        elseif(WaveExists($(dfName+":instrument:parameters:L1mm")))
1441                Wave wSampleToSourceDist = $(dfName+":instrument:parameters:L1mm")
1442                value = wSampleToSourceDist[0]/1000
1443        elseif(WaveExists($(dfName+":instrument:parameters:derived_parameters:L1mm"))) 
1444                Wave wSampleToSourceDist = $(dfName+":instrument:parameters:derived_parameters:L1mm")
1445                value = wSampleToSourceDist[0]/1000
1446        else
1447                print "Can't find L1 in " + fname
1448        endif
1449       
1450        // [davidm]
1451        //KillWaves wSourceToDetectorDist
1452               
1453        return(value)
1454end
1455
1456//sample to detector distance (meters)
1457Function getSDD(fname)
1458        String fname
1459        Variable value
1460        // your code returning value
1461        variable err
1462        string dfName = ""
1463       
1464        // [davidm]
1465        //err = hdfRead(fname, dfName)
1466        //err not handled here
1467
1468        hdfReadSimulated(fname, dfName)
1469       
1470        variable flag = 0
1471        if(WaveExists($(dfName+":instrument:parameters:L2"))) //canonical location
1472                flag = 1
1473        elseif(WaveExists($(dfName+":instrument:parameters:L2mm")))
1474                flag = 1
1475        elseif(WaveExists($(dfName+":instrument:parameters:derived_parameters:L2mm")))
1476                flag = 1
1477        endif
1478       
1479        if(flag == 0)
1480                err = hdfRead(fname, dfName)
1481                //err not handled here
1482        endif
1483
1484        //workaround for bad HDF5 dataset
1485        if(WaveExists($(dfName+":instrument:parameters:L2"))) //canonical location
1486                Wave wSourceToDetectorDist = $(dfName+":instrument:parameters:L2")
1487                value = wSourceToDetectorDist[0]/1000
1488        elseif(WaveExists($(dfName+":instrument:parameters:L2mm")))
1489                Wave wSourceToDetectorDist = $(dfName+":instrument:parameters:L2mm")
1490                value = wSourceToDetectorDist[0]/1000
1491        elseif(WaveExists($(dfName+":instrument:parameters:derived_parameters:L2mm"))) 
1492                Wave wSourceToDetectorDist = $(dfName+":instrument:parameters:derived_parameters:L2mm")
1493                value = wSourceToDetectorDist[0]/1000
1494        else
1495                print "Can't find L2 in " + fname
1496        endif
1497       
1498        // [davidm]
1499        //KillWaves wSourceToDetectorDist
1500               
1501        return(value)
1502end
1503
1504//sample to detector distance (meters)
1505Function WriteSDDToHeader(fname,sdd)
1506        String fname
1507        Variable sdd
1508       
1509// your writer here
1510        Wave wSDD
1511        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1512        Make /N=(1,1) wSDD
1513        String groupName = "/instrument/parameters"
1514        String varName = "L2"
1515        wSDD[0] = sdd * 1000 //
1516        // your code returning value
1517        variable err
1518        err = hdfWrite(fname, groupName, varName, wSDD)
1519        KillWaves wSDD
1520        //err not handled here
1521       
1522        return(0)
1523End
1524
1525//lateral detector offset (centimeters)
1526Function getDetectorOffset(fname)
1527        String fname
1528        Variable value
1529        // your code returning value
1530        variable err
1531        string dfName = ""
1532        err = hdfRead(fname, dfName)
1533        //err not handled here
1534
1535        Wave wDetectorOffset = $(dfName+":instrument:detector:detector_x") //is this correct
1536        value = wDetectorOffset[0]/10
1537        KillWaves wDetectorOffset
1538       
1539        return(value)
1540end
1541
1542//Beamstop diameter (millimeters)
1543Function getBSDiameter(fname)
1544        String fname
1545        Variable value
1546        // your code returning value
1547        variable err
1548        string dfName = ""
1549        err = hdfRead(fname, dfName)
1550        //err not handled here
1551
1552        if(WaveExists($(dfName+":instrument:parameters:BSdiam"))) //canonical location
1553                Wave wBSdiameter = $(dfName+":instrument:parameters:BSdiam")
1554                value = wBSdiameter[0]
1555        elseif(WaveExists($(dfName+":instrument:parameters:BSXmm")))
1556                Wave wBSdiameter = $(dfName+":instrument:parameters:BSXmm")
1557                value = wBSdiameter[0]
1558        else
1559                print "Can't find Beamstop Diameter in " + fname
1560        endif
1561       
1562        KillWaves wBSdiameter
1563       
1564        return(value)   
1565end
1566
1567//beam stop diameter (millimeters)
1568Function WriteBeamStopDiamToHeader(fname,bs)
1569        String fname
1570        Variable bs     
1571       
1572        // your writer here
1573        Wave wBS
1574        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1575        Make /N=(1,1) wBS
1576        String groupName = "/instrument/parameters"
1577        String varName = "BSdiam"
1578        wBS[0] = bs //
1579        // your code returning value
1580        variable err
1581        err = hdfWrite(fname, groupName, varName, wBS)
1582        KillWaves wBS
1583        //err not handled here
1584        return(0)
1585End
1586
1587//source aperture diameter (millimeters)
1588Function getSourceApertureDiam(fname)
1589        String fname
1590        Variable value
1591        // your code returning value
1592        variable err
1593        string dfName = ""
1594        err = hdfRead(fname, dfName)
1595        //err not handled here
1596
1597        if(WaveExists($(dfName+":instrument:parameters:EApX")))
1598                Wave wSourceApertureDiam = $(dfName+":instrument:parameters:EApX") // canonical location
1599                value = wSourceApertureDiam[0]
1600        elseif(WaveExists($(dfName+":instrument:parameters:derived_parameters:EApXmm")))
1601                Wave wSourceApertureDiam = $(dfName+":instrument:parameters:derived_parameters:EApXmm")
1602                value = wSourceApertureDiam[0]
1603        else
1604                print "Can't find Source Aperture Diameter in " + fname
1605        endif
1606       
1607        KillWaves wSourceApertureDiam
1608       
1609        return(value)
1610end
1611
1612//Source Aperture diameter (millimeters)
1613Function WriteSourceApDiamToHeader(fname,source)
1614        String fname
1615        Variable source
1616       
1617        // your writer here
1618        Wave wsource
1619        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1620        Make /N=(1,1) wsource
1621        String groupName = "/instrument/parameters"
1622        String varName = "EApX"
1623        wsource[0] = source //
1624        // your code returning value
1625        variable err
1626        err = hdfWrite(fname, groupName, varName, wsource)
1627        KillWaves wsource
1628        //err not handled here
1629        return(0)
1630End
1631
1632//sample aperture diameter (millimeters)
1633Function getSampleApertureDiam(fname)
1634        String fname
1635        Variable value
1636        // your code returning value
1637        variable err
1638        string dfName = ""
1639        err = hdfRead(fname, dfName)
1640        //err not handled here
1641
1642        if(WaveExists($(dfName+":sample:diameter"))) //canonical location
1643                Wave wSampleApertureDiam = $(dfName+":sample:diameter")
1644                value = wSampleApertureDiam[0]
1645        elseif(WaveExists($(dfName+":instrument:parameters:autoSampleAp:diameter"))) //canonical location
1646                Wave wSampleApertureDiam = $(dfName+":instrument:parameters:autoSampleAp:diameter")
1647                value = wSampleApertureDiam[0]
1648        elseif (WaveExists($(dfName+":instrument:sample_aperture:geometry:shape:SApXmm")))
1649                Wave wSampleApertureDiam = $(dfName+":instrument:sample_aperture:geometry:shape:SApXmm")
1650                value = wSampleApertureDiam[0]
1651        else
1652                print "Can't find Sample Aperture Diameter in " + fname
1653        endif
1654       
1655        KillWaves wSampleApertureDiam
1656
1657        return(value)   
1658end
1659
1660//Sample Aperture diameter (millimeters)
1661Function WriteSampleApDiamToHeader(fname,source)
1662        String fname
1663        Variable source
1664       
1665        // your writer here
1666        Wave wsource
1667        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1668        Make /N=(1,1) wsource
1669        String groupName = "/sample"
1670        String varName = "diameter"
1671        wsource[0] = source //
1672        // your code returning value
1673        variable err
1674        err = hdfWrite(fname, groupName, varName, wsource)
1675        KillWaves wsource
1676        //err not handled here
1677        return(0)
1678End
1679
1680//source AP to Sample AP distance (meters)
1681Function getSourceToSampleDist(fname)
1682        String fname
1683       
1684        Variable value
1685       
1686        // your code returning value
1687        variable err
1688        string dfName = ""
1689               
1690        err = hdfRead(fname, dfName)
1691        //err not handled here
1692       
1693        if(WaveExists($(dfName+":instrument:parameters:L1"))) //canonical location
1694                Wave wSourceToSampleDist = $(dfName+":instrument:parameters:L1")       
1695                value = wSourceToSampleDist[0]/1000
1696        elseif(WaveExists($(dfName+":instrument:parameters:L1mm")))
1697                Wave wSourceToSampleDist = $(dfName+":instrument:parameters:L1mm")
1698                value = wSourceToSampleDist[0]/1000
1699        elseif(WaveExists($(dfName+":instrument:parameters:derived_parameters:L1mm")))
1700                Wave wSourceToSampleDist = $(dfName+":instrument:parameters:derived_parameters:L1mm")
1701                value = wSourceToSampleDist[0]/1000
1702        else
1703                print "Can't find L1 in " + fname
1704        endif
1705       
1706        KillWaves wSourceToSampleDist   
1707               
1708        return(value)
1709end
1710
1711//Source aperture to sample aperture distance (meters)
1712Function WriteSrcToSamDistToHeader(fname,SSD)
1713        String fname
1714        Variable SSD
1715       
1716// your writer here
1717        Wave wSSD
1718        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1719        Make /N=(1,1) wSSD
1720        String groupName = "/instrument/parameters"
1721        String varName = "L1"
1722        wSSD[0] = SSD * 1000 //input in metres, converted to mm for saving to file.
1723        // your code returning value
1724        variable err
1725        err = hdfWrite(fname, groupName, varName, wSSD)
1726        KillWaves wSSD
1727        //err not handled here
1728       
1729        return(0)
1730End
1731
1732//wavelength (Angstroms)
1733Function getWavelength(fname)
1734        String fname
1735        Variable value
1736        // your code returning value
1737        variable err
1738        string dfName = ""
1739        //err = hdfRead(fname, dfName)
1740        //err not handled here
1741
1742        // [davidm]
1743        hdfReadSimulated(fname, dfName)
1744
1745        variable flag = 0
1746        if(WaveExists($(dfName+":instrument:velocity_selector:wavelength")))  // canonical location
1747                flag = 1
1748        elseif(WaveExists($(dfName+":instrument:velocity_selector:Lambda")))
1749                flag = 1
1750        elseif(WaveExists($(dfName+":data:Lambda")))
1751                flag = 1
1752        elseif(WaveExists($(dfName+":data:LambdaA")))
1753                flag = 1
1754        elseif(WaveExists($(dfName+":instrument:velocity_selector:LambdaA")))
1755                flag = 1
1756        endif
1757
1758        if(flag == 0)
1759                err = hdfRead(fname, dfName)
1760                //err not handled here
1761        endif   
1762
1763        //      Wave wWavelength = $(dfName+":data:LambdaA")
1764        //change 22/12/09 nha
1765        // all these locations to be deprecated
1766        if(WaveExists($(dfName+":instrument:velocity_selector:wavelength")))  // canonical location
1767                Wave wWavelength = $(dfName+":instrument:velocity_selector:wavelength")
1768                value = wWavelength[0]
1769        elseif(WaveExists($(dfName+":instrument:velocity_selector:Lambda")))
1770                Wave wWavelength = $(dfName+":instrument:velocity_selector:Lambda")
1771                value = wWavelength[0]
1772        elseif(WaveExists($(dfName+":data:Lambda")))
1773                Wave wWavelength = $(dfName+":data:Lambda")
1774                value = wWavelength[0]
1775        elseif(WaveExists($(dfName+":data:LambdaA")))
1776                Wave wWavelength = $(dfName+":data:LambdaA")
1777                value = wWavelength[0]
1778        elseif(WaveExists($(dfName+":instrument:velocity_selector:LambdaA")))
1779                Wave wWavelength = $(dfName+":instrument:velocity_selector:LambdaA")
1780                value = wWavelength[0]
1781        else
1782                print "Can't find Lambda in " + fname
1783        endif
1784       
1785        // [davidm]
1786        //KillWaves wWavelength
1787       
1788        return(value)
1789end
1790
1791//wavelength (Angstroms)
1792Function WriteWavelengthToHeader(fname,wavelength)
1793        String fname
1794        Variable wavelength
1795       
1796        // your writer here
1797        Wave wWavelength
1798        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1799        Make /N=(1,1) wWavelength
1800        String groupName = "/instrument/velocity_selector"
1801        String varName = "wavelength"
1802        wWavelength[0] = wavelength //
1803        // your code returning value
1804        variable err
1805        err = hdfWrite(fname, groupName, varName, wWavelength)
1806       
1807        //and because Bill Hamilton is not happy with the NeXus naming, we write it to 3 other places
1808        //groupName = "/instrument/parameters"
1809        //err = hdfWrite(fname, groupName, varName, wWavelength)
1810        //velocity_selector group causes Igor crash in some cases
1811        //groupName = "/instrument/velocity_selector"
1812        //err = hdfWrite(fname, groupName, varName, wWavelength)
1813        //
1814        //groupName = "/data"
1815        //varName = "lambda"
1816        //err = hdfWrite(fname, groupName, varName, wWavelength)
1817       
1818        KillWaves wWavelength
1819        //err not handled here
1820
1821        return(0)
1822End
1823
1824
1825
1826//wavelength spread (FWHM)
1827Function getWavelengthSpread(fname)
1828        String fname
1829        Variable value
1830        // your code returning value
1831        variable err
1832        string dfName = ""
1833        //err = hdfRead(fname, dfName)
1834        //err not handled here
1835
1836        // [davidm]
1837        hdfReadSimulated(fname, dfName)
1838
1839        variable flag = 0
1840        if(WaveExists($(dfName+":instrument:velocity_selector:wavelength_spread")))  //canonical location
1841                flag = 1
1842        elseif(WaveExists($(dfName+":instrument:velocity_selector:LambdaResFWHM_percent")))
1843                flag = 1
1844        elseif(WaveExists($(dfName+":instrument:parameters:LambdaResFWHM_percent")))
1845                flag = 1
1846        endif
1847
1848        if(flag == 0)
1849                err = hdfRead(fname, dfName)
1850                //err not handled here
1851        endif   
1852
1853        //velocity_selector group causes Igor crash
1854        if(WaveExists($(dfName+":instrument:velocity_selector:wavelength_spread")))  //canonical location
1855                Wave wWavelengthSpread = $(dfName+":instrument:velocity_selector:wavelength_spread")
1856                value = wWavelengthSpread[0]   
1857        elseif(WaveExists($(dfName+":instrument:velocity_selector:LambdaResFWHM_percent")))
1858                Wave wWavelengthSpread = $(dfName+":instrument:velocity_selector:LambdaResFWHM_percent")
1859                value = wWavelengthSpread[0]   
1860        elseif(WaveExists($(dfName+":instrument:parameters:LambdaResFWHM_percent")))
1861                Wave wWavelengthSpread = $(dfName+":instrument:parameters:LambdaResFWHM_percent")
1862                value = wWavelengthSpread[0]   
1863        else
1864                print "Can't find Wavelength Spread in " + fname
1865        endif
1866       
1867        KillWaves wWavelengthSpread
1868       
1869        return(value)
1870end
1871
1872//wavelength spread (FWHM)
1873Function WriteWavelengthDistrToHeader(fname,wavelengthSpread)
1874        String fname
1875        Variable wavelengthSpread
1876       
1877        // your writer here
1878        Wave wWavelengthSpread
1879        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
1880        Make /N=(1,1) wWavelengthSpread
1881        //velocity_selector group causes Igor crash
1882        String groupName = "/instrument/velocity_selector"
1883        String varName = "wavelength_spread"
1884
1885        wWavelengthSpread[0] = wavelengthSpread
1886        // your code returning value
1887        variable err
1888        err = hdfWrite(fname, groupName, varName, wWavelengthSpread)
1889        KillWaves wWavelengthSpread
1890        //err not handled here
1891               
1892        return(0)
1893End
1894
1895// physical x-dimension of a detector pixel, in mm
1896Function getDetectorPixelXSize(fname)
1897        String fname
1898        Variable value
1899       
1900        // your code here returning value
1901        variable err
1902        string dfName = ""
1903        err = hdfRead(fname, dfName)
1904        //err not handled here
1905
1906        Wave wActiveArea = $(dfName+":instrument:detector:active_height")
1907        Wave w_x_bin = $(dfName+":instrument:detector:x_bin")
1908        Variable numPixels = dimsize(w_x_bin, 0) - 1 // davidm: detector has 192 bins! not 193
1909        value = wActiveArea[0]/numPixels
1910        KillWaves wActiveArea
1911        KillWaves w_x_bin
1912       
1913        return(value)
1914end
1915
1916// physical y-dimension of a detector pixel, in mm
1917Function getDetectorPixelYSize(fname)
1918        String fname
1919        Variable value
1920       
1921        // your code here returning value
1922        variable err
1923        string dfName = ""
1924        err = hdfRead(fname, dfName)
1925        //err not handled here
1926
1927        Wave wActiveArea = $(dfName+":instrument:detector:active_width")
1928        Wave w_y_bin = $(dfName+":instrument:detector:y_bin")
1929        Variable numPixels = dimsize(w_y_bin, 0) - 1 // davidm: detector has 192 bins! not 193
1930        value = wActiveArea[0]/numPixels
1931        KillWaves wActiveArea
1932        KillWaves w_y_bin
1933                       
1934        return(value)
1935end
1936
1937//transmission detector count (unused, return 0)
1938//
1939Function getTransDetectorCounts(fname)
1940        String fname
1941       
1942        Variable value
1943       
1944        // your code returning value
1945        //print "not implemented: getTransDetectorCounts"
1946       
1947        return(0)
1948end
1949
1950
1951//total count time (seconds)
1952Function getCountTime(fname)
1953        String fname
1954        Variable value
1955        // your code returning value
1956        variable err
1957        string dfName = ""
1958        //err = hdfRead(fname, dfName)
1959        //err not handled here
1960       
1961        // [davidm]
1962        hdfReadSimulated(fname, dfName)
1963        if (exists(dfName+":monitor:bm1_time")!= 1)
1964                err = hdfRead(fname, dfName)
1965                //err not handled here
1966        endif
1967
1968        Wave wTime1 = $(dfName+":monitor:bm1_time")
1969       
1970        if (WaveExists(wTime1))
1971                value = wTime1[0]
1972        else
1973                print "Can't find Total Count Time in " + fname
1974        endif
1975       
1976        // [davidm]
1977        //KillWaves wTime1
1978       
1979        if (value == 0)
1980                print "***total count time is ZERO*** and has been reset to 1.0"
1981                value = 1
1982        endif
1983       
1984        return(value)
1985end
1986
1987
1988Function getPhysicalWidth(fname)
1989        String fname
1990        Variable value
1991        // your code returning value
1992        variable err
1993        string dfName = ""
1994        err = hdfRead(fname, dfName)
1995        //err not handled here
1996
1997        Wave wPhysicalWidth = $(dfName+":instrument:detector:active_width")
1998
1999        if (WaveExists(wPhysicalWidth))
2000                value = wPhysicalWidth[0]/10
2001        else
2002                print "Can't find Physical Width in " + fname
2003        endif
2004       
2005        KillWaves wPhysicalWidth
2006               
2007        return(value)
2008end
2009
2010Function/S getSICSVersion(fname)
2011        String fname
2012        String str
2013        // your code returning value
2014        variable err
2015        string dfName = ""
2016        //err = hdfRead(fname, dfName)
2017        //err not handled here
2018       
2019        hdfReadSimulated(fname, dfName)
2020        if (exists(dfName+":sics_release") != 1)
2021                err = hdfRead(fname, dfName)
2022                //err not handled here
2023        endif
2024
2025        Wave/T wSICSVersion = $(dfName+":sics_release")
2026       
2027        if (WaveExists(wSICSVersion))
2028                str = wSICSVersion[0]
2029        else
2030                print "Can't find SICS Version in " + fname
2031                str = ""
2032        endif
2033       
2034        // [davidm]
2035        // KillWaves wSICSVersion
2036       
2037        return(str)
2038end
2039
2040Function/S getHDFversion(fname)
2041        String fname
2042        String str
2043        // your code returning value
2044        variable err
2045        string dfName = ""
2046        string attribute = "HDF5_Version"
2047       
2048        // [davidm]
2049        hdfReadAttributeSimulated(fname, dfName, "/", 1, attribute)
2050        if (exists(dfName+":"+attribute) != 1)
2051                err = hdfReadAttribute(fname, dfName, "/", 1, attribute)
2052                //err not handled here
2053        endif
2054
2055//      string attribute ="signal"
2056//      err = hdfReadAttribute(fname, dfName, "/entry/data/hmm_xy", 2, attribute)
2057        //err not handled here
2058
2059        Wave/T wHDF5_Version = $(dfName+":"+attribute)
2060       
2061        if (WaveExists(wHDF5_Version))
2062                str = wHDF5_Version[0] 
2063        else
2064                print "Can't find HDF Version in " + fname
2065                str = ""
2066        endif
2067       
2068//      KillWaves wHDF5_Version
2069
2070        return(str)
2071end
2072
2073// read the detector deadtime (in seconds)
2074Function getDetectorDeadtime(fname)
2075        String fname
2076       
2077        return(0)
2078end
2079
2080// Write the detector deadtime to the file header (in seconds)
2081Function WriteDeadtimeToHeader(fname,num)
2082        String fname
2083        Variable num
2084       
2085        return(0)
2086End
2087
2088//reads the wavelength from a reduced data file (not very reliable)
2089// - does not work with NSORTed files
2090// - only used in FIT/RPA (which itself is almost NEVER used...)
2091//
2092// DOES NOT NEED TO BE CHANGED IF USING NCNR DATA WRITER
2093Function GetLambdaFromReducedData(tempName)
2094        String tempName
2095       
2096        String junkString
2097        Variable lambdaFromFile, fileVar
2098        lambdaFromFile = 6.0
2099        Open/R/P=catPathName fileVar as tempName
2100        FReadLine fileVar, junkString
2101        FReadLine fileVar, junkString
2102        FReadLine fileVar, junkString
2103        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
2104                FReadLine/N=11 fileVar, junkString
2105                FReadLine/N=10 fileVar, junkString
2106                lambdaFromFile = str2num(junkString)
2107        endif
2108        Close fileVar
2109       
2110        return(lambdaFromFile)
2111End
2112
2113/////   TRANSMISSION RELATED FUNCTIONS    ////////
2114//box coordinate are returned by reference
2115//
2116// box to sum over is bounded (x1,y1) to (x2,y2)
2117//
2118// this function returns the bounding coordinates as stored in
2119// the header
2120//
2121// if not using the NCNR Transmission module, this function default to
2122// returning 0000, and no changes needed
2123Function getXYBoxFromFile(fname,x1,x2,y1,y2)
2124        String fname
2125        Variable &x1,&x2,&y1,&y2
2126       
2127        // return your bounding box coordinates or default values of 0
2128        x1=0
2129        y1=0
2130        x2=0
2131        y2=0
2132
2133        // your code returning value
2134        variable err
2135        string dfName = ""
2136        //err = hdfRead(fname, dfName)
2137        //err not handled here
2138
2139        // [davidm]
2140        hdfReadSimulated(fname, dfName)
2141       
2142        if(!WaveExists($(dfName+":reduce:x1")))
2143                err = hdfRead(fname, dfName)
2144                //err not handled here
2145        endif
2146       
2147        Wave wX1 = $(dfName+":reduce:x1")
2148        if (waveexists(wX1) == 0)
2149                //Waves don't exists which means an XY box has not been set for this file.
2150                //Hence return 0 bounding boxes (default)
2151        else
2152                x1 = wX1[0]
2153                Wave wX2 = $(dfName+":reduce:x2")
2154                x2 = wX2[0]
2155                Wave wY1 = $(dfName+":reduce:y1")
2156                y1 = wY1[0]
2157                Wave wY2 = $(dfName+":reduce:y2")
2158                y2 = wY2[0]
2159        endif
2160       
2161        // [davidm]
2162        //KillWaves/Z wX1, wX2, wY1, wY2
2163        return(0)
2164
2165End
2166
2167// Writes the coordinates of the box to the header after user input
2168//
2169// box to sum over bounded (x1,y1) to (x2,y2)
2170//
2171// if not using the NCNR Transmission module, this function is null
2172Function WriteXYBoxToHeader(fname,x1,x2,y1,y2)
2173        String fname
2174        Variable x1,x2,y1,y2
2175
2176        String groupName = "/reduce"
2177        variable err
2178               
2179        Wave wX1
2180        Make/O/N=(1,1) wX1
2181        Wave wX2
2182        Make/O/N=(1,1) wX2
2183        Wave wY1
2184        Make/O/N=(1,1) wY1
2185        Wave wY2
2186        Make/O/N=(1,1) wY2
2187               
2188        wX1[0] = x1
2189        wX2[0] = x2
2190        wY1[0] = y1
2191        wY2[0] = y2     
2192       
2193        String varName = "x1"   
2194        err = hdfWrite(fname, groupName, varName,wX1)
2195        varName = "x2"
2196        err = hdfWrite(fname, groupName, varName,wX2)
2197        varName = "y1"
2198        err = hdfWrite(fname, groupName, varName,wY1)
2199        varName = "y2"
2200        err = hdfWrite(fname, groupName, varName,wY2)   
2201       
2202        KillWaves wX1,wX2,wY1,wY2
2203       
2204        //err not handled here
2205        return(0)       
2206
2207End
2208
2209// for transmission calculation, writes an NCNR-specific alphanumeric identifier
2210// (suffix of the data file)
2211//
2212//AJJ June 3 2010 - Note!! For ANSTO data the "suffix" is just the filename.
2213Function WriteAssocFileSuffixToHeader(fname,assoc_fname)
2214        String fname,assoc_fname
2215               
2216// your writer here
2217        Wave/T wAssoc_fname
2218        //nha ??? Should make this wave in our own DataFolder to avoid clashing names.
2219        Make/T /N=(1,1) wAssoc_fname
2220       
2221        String varName =""
2222        String groupName = "/reduce"
2223        if(isTransFile(fname))
2224                varName = "empty_beam_file_name"
2225        elseif(isScatFile(fname))
2226                varName = "transmission_file_name"
2227        endif
2228
2229        wAssoc_fname[0] = assoc_fname
2230        // your code returning value
2231        variable err
2232        err = hdfWrite(fname, groupName, varName, wAssoc_fname)
2233        KillWaves wAssoc_fname
2234        //err not handled here
2235        return(0)
2236end
2237
2238Function/S GetFileAssoc(fname)
2239        String fname
2240       
2241        String assoc_fname
2242        String groupName = ":reduce:"
2243       
2244        String varName = ""
2245        if(isTransFile(fname))
2246                varName = "empty_beam_file_name"
2247        elseif(isScatFile(fname))
2248                varName = "transmission_file_name"
2249        endif
2250       
2251        variable err
2252        string dfName = ""
2253        err = hdfRead(fname, dfName)
2254        //err not handled here
2255
2256        Wave/T wAssoc_fname = $(dfName+groupName+varName)
2257        if (waveexists(wAssoc_fname) == 1)
2258                assoc_fname =wAssoc_fname[0]   
2259        else
2260                assoc_fname = ""
2261        endif
2262        KillWaves/Z wAssoc_fname
2263       
2264        return(assoc_fname)
2265end
2266
2267Function hdfReadAttribute(fname, dfName, nodeName, nodeType, attributeStr)
2268// this is a copy of hdfRead, and could be incorporated back into hdfRead.
2269       
2270        String fname, &dfName, nodeName, attributeStr
2271        variable nodeType
2272        String nxentryName
2273        variable err=0,fileID   
2274        String cDF = getDataFolder(1), temp
2275        String fname_temp = ParseFilePath(0, fname, ":", 1, 0)
2276
2277       
2278        String fileSuffix
2279       
2280        if(strsearch(fname_temp,".nx.hdf",0,2)>=0)
2281                fileSuffix=".nx.hdf"
2282        else
2283                err = 1
2284                abort "unrecognised file suffix. Not .nx.hdf"
2285        endif
2286       
2287        dfName = "root:packages:quokka:"+removeending(fname_temp,fileSuffix)
2288       
2289        //folder must already exist i.e. hdfRead must have already been called
2290        if(!DataFolderExists(dfName))
2291                // possibly call an hdfRead from here
2292                return err
2293        endif
2294       
2295        //test for the name of nxentry
2296        if(DataFolderExists(dfName+":"+removeending(fname_temp,fileSuffix)))
2297                nxentryName = removeending(fname_temp,fileSuffix)
2298        elseif(DataFolderExists(dfName+":"+"entry1"))
2299                nxentryName = "entry1"
2300        else
2301                print "NXentry not found"
2302                return err
2303        endif
2304       
2305        //this is the stupid bit.
2306        // If you're looking for attributes of the root node, then nodename = "/"
2307        // If you're looking for attributes     of the nxentry node, then e.g. nodename ="/entry/instrument"
2308        // /entry is replaced with nxentryName
2309        nodeName = ReplaceString("entry", nodeName, nxentryName)       
2310       
2311        //convert nodeName to data folder string
2312        String dfNodeName = nodeName
2313        dfNodeName = ReplaceString( "/", nodeName, ":")
2314        dfName = dfName + dfNodeName
2315        if(nodeType == 2) //data item (dataset)
2316                //remove the end of dfName so that it points to a folder and not a dataset
2317                variable length = strlen(dfName)
2318                variable position = strsearch(dfName, ":", length, 1) // search backwards to find last :
2319                // to do - truncate string to remove dataset
2320                string truncate = "\"%0." + num2str(position) + "s\""
2321                sprintf dfName, truncate, dfName
2322        endif
2323       
2324        setDataFolder dfName
2325       
2326        try     
2327                HDF5OpenFile /R /Z fileID  as fname
2328                if(!fileID)
2329                        err = 1
2330                        abort "couldn't load HDF5 file"
2331                endif
2332
2333                HDF5LoadData /O /Q /Z /TYPE=(nodeType) /A=attributeStr, fileID, nodeName
2334
2335                if (V_flag!=0)
2336                        print "couldn't load attribute " + attributeStr
2337                endif
2338        catch
2339
2340        endtry
2341        if(fileID)
2342                HDF5CloseFile /Z fileID
2343        endif
2344
2345// add the name of the root node to dfName
2346// in the case of sensitivity files aka DIV files, don't append a root node to dfName
2347        if(DataFolderExists(dfName+":"+removeending(fname_temp,fileSuffix)))
2348                dfName = dfName+":"+removeending(fname_temp,fileSuffix)  //for files written Dec 2009 and after
2349        elseif(DataFolderExists(dfName+":"+"entry1"))
2350                dfName = dfName+":entry1" //for files written before Dec 2009
2351        endif
2352
2353        setDataFolder $cDF
2354        return err
2355end
2356Function hdfReadAttributeSimulated(fname, dfName, nodeName, nodeType, attributeStr)
2357// this is a copy of hdfRead, and could be incorporated back into hdfRead.
2358       
2359        String fname, &dfName, nodeName, attributeStr
2360        variable nodeType
2361        String nxentryName
2362        variable err=0,fileID   
2363        String cDF = getDataFolder(1), temp
2364        String fname_temp = ParseFilePath(0, fname, ":", 1, 0)
2365
2366       
2367        String fileSuffix
2368       
2369        if(strsearch(fname_temp,".nx.hdf",0,2)>=0)
2370                fileSuffix=".nx.hdf"
2371        else
2372                err = 1
2373                abort "unrecognised file suffix. Not .nx.hdf"
2374        endif
2375       
2376        dfName = "root:packages:quokka:"+removeending(fname_temp,fileSuffix)
2377       
2378        //folder must already exist i.e. hdfRead must have already been called
2379        if(!DataFolderExists(dfName))
2380                // possibly call an hdfRead from here
2381                return err
2382        endif
2383       
2384        //test for the name of nxentry
2385        if(DataFolderExists(dfName+":"+removeending(fname_temp,fileSuffix)))
2386                nxentryName = removeending(fname_temp,fileSuffix)
2387        elseif(DataFolderExists(dfName+":"+"entry1"))
2388                nxentryName = "entry1"
2389        else
2390                print "NXentry not found"
2391                return err
2392        endif
2393       
2394        //this is the stupid bit.
2395        // If you're looking for attributes of the root node, then nodename = "/"
2396        // If you're looking for attributes     of the nxentry node, then e.g. nodename ="/entry/instrument"
2397        // /entry is replaced with nxentryName
2398        nodeName = ReplaceString("entry", nodeName, nxentryName)       
2399       
2400        //convert nodeName to data folder string
2401        String dfNodeName = nodeName
2402        dfNodeName = ReplaceString( "/", nodeName, ":")
2403        dfName = dfName + dfNodeName
2404        if(nodeType == 2) //data item (dataset)
2405                //remove the end of dfName so that it points to a folder and not a dataset
2406                variable length = strlen(dfName)
2407                variable position = strsearch(dfName, ":", length, 1) // search backwards to find last :
2408                // to do - truncate string to remove dataset
2409                string truncate = "\"%0." + num2str(position) + "s\""
2410                sprintf dfName, truncate, dfName
2411        endif
2412       
2413        setDataFolder dfName
2414       
2415//      try     
2416//              HDF5OpenFile /R /Z fileID  as fname
2417//              if(!fileID)
2418//                      err = 1
2419//                      abort "couldn't load HDF5 file"
2420//              endif
2421//
2422//              HDF5LoadData /O /Q /Z /TYPE=(nodeType) /A=attributeStr, fileID, nodeName
2423//
2424//              if (V_flag!=0)
2425//                      print "couldn't load attribute " + attributeStr
2426//              endif
2427//      catch
2428//
2429//      endtry
2430//      if(fileID)
2431//              HDF5CloseFile /Z fileID
2432//      endif
2433
2434// add the name of the root node to dfName
2435// in the case of sensitivity files aka DIV files, don't append a root node to dfName
2436        if(DataFolderExists(dfName+":"+removeending(fname_temp,fileSuffix)))
2437                dfName = dfName+":"+removeending(fname_temp,fileSuffix)  //for files written Dec 2009 and after
2438        elseif(DataFolderExists(dfName+":"+"entry1"))
2439                dfName = dfName+":entry1" //for files written before Dec 2009
2440        endif
2441
2442        setDataFolder $cDF
2443        return err
2444end
2445
2446Function hdfRead(fname, dfName)
2447        //Reads hdf5 file into root:packages:quokka:fname
2448        //N. Hauser. 16/12/08
2449        // 29/1/09 - hdf file must have .nx.hdf or .div suffix
2450       
2451        String fname, &dfName
2452        variable err=0,fileID
2453        String cDF = getDataFolder(1), temp
2454        String fname_temp = ParseFilePath(0, fname, ":", 1, 0)
2455               
2456        String fileSuffix
2457        if(strsearch(fname_temp,".nx.hdf",0,2)>=0)
2458                fileSuffix=".nx.hdf"
2459        //elseif(strsearch(fname_temp,".div",0,2)>=0)
2460        //      fileSuffix=".div"
2461        else
2462                err = 1
2463                abort "unrecognised file suffix. Not .nx.hdf"
2464        endif
2465       
2466        dfName = "root:packages:quokka:"+removeending(fname_temp,fileSuffix)
2467       
2468        //if(!DataFolderExists(dfName))
2469        //      return err
2470        //else         
2471                newDataFolder /O root:packages
2472                newDataFolder /O /S root:packages:quokka
2473                newDataFolder /O /S $dfName
2474        //endif
2475       
2476        try     
2477                HDF5OpenFile /R /Z fileID  as fname
2478                if(!fileID)
2479                        err = 1
2480                        abort "couldn't load HDF5 file"
2481                endif
2482                HDF5LoadGroup /O /R /Z  :, fileID, "."
2483        catch
2484
2485        endtry
2486        if(fileID)
2487                HDF5CloseFile /Z fileID
2488        endif
2489
2490        // add the name of the root node to dfName
2491        // in the case of sensitivity files aka DIV files, don't append a root node to dfName
2492        if(DataFolderExists(dfName+":"+removeending(fname_temp,fileSuffix)))
2493                dfName = dfName+":"+removeending(fname_temp,fileSuffix)  //for files written Dec 2009 and after
2494        elseif(DataFolderExists(dfName+":"+"entry1"))
2495                dfName = dfName+":entry1" //for files written before Dec 2009
2496        endif
2497
2498        setDataFolder $cDF
2499        return err
2500end
2501Function hdfReadSimulated(fname, dfName)
2502        //Reads hdf5 file into root:packages:quokka:fname
2503        //N. Hauser. 16/12/08
2504        // 29/1/09 - hdf file must have .nx.hdf or .div suffix
2505       
2506        String fname, &dfName
2507        variable err=0,fileID
2508        String cDF = getDataFolder(1), temp
2509        String fname_temp = ParseFilePath(0, fname, ":", 1, 0)
2510               
2511        String fileSuffix
2512        if(strsearch(fname_temp,".nx.hdf",0,2)>=0)
2513                fileSuffix=".nx.hdf"
2514        //elseif(strsearch(fname_temp,".div",0,2)>=0)
2515        //      fileSuffix=".div"
2516        else
2517                err = 1
2518                abort "unrecognised file suffix. Not .nx.hdf"
2519        endif
2520       
2521        dfName = "root:packages:quokka:"+removeending(fname_temp,fileSuffix)
2522       
2523        //if(!DataFolderExists(dfName))
2524        //      return err
2525        //else         
2526                newDataFolder /O root:packages
2527                newDataFolder /O /S root:packages:quokka
2528                newDataFolder /O /S $dfName
2529        //endif
2530       
2531//      try     
2532//              HDF5OpenFile /R /Z fileID  as fname
2533//              if(!fileID)
2534//                      err = 1
2535//                      abort "couldn't load HDF5 file"
2536//              endif
2537//              HDF5LoadGroup /O /R /Z  :, fileID, "."
2538//      catch
2539//
2540//      endtry
2541//      if(fileID)
2542//              HDF5CloseFile /Z fileID
2543//      endif
2544
2545        // add the name of the root node to dfName
2546        // in the case of sensitivity files aka DIV files, don't append a root node to dfName
2547        if(DataFolderExists(dfName+":"+removeending(fname_temp,fileSuffix)))
2548                dfName = dfName+":"+removeending(fname_temp,fileSuffix)  //for files written Dec 2009 and after
2549        elseif(DataFolderExists(dfName+":"+"entry1"))
2550                dfName = dfName+":entry1" //for files written before Dec 2009
2551        endif
2552
2553        setDataFolder $cDF
2554        return err
2555end
2556
2557Function hdfWrite(fname, groupName, varName, wav)
2558        //Write Wave 'wav' to hdf5 file 'fname'
2559        //N. Hauser. nha 8/1/09
2560               
2561        String fname, groupName, varName
2562        Wave wav
2563       
2564        variable err=0, fileID,groupID
2565        String cDF = getDataFolder(1), temp
2566        String fname_temp = ParseFilePath(0, fname, ":", 1, 0)
2567        String NXentry_name
2568                       
2569        try     
2570                HDF5OpenFile/Z fileID  as fname  //open file read-write
2571                if(!fileID)
2572                        err = 1
2573                        abort "HDF5 file does not exist"
2574                endif
2575               
2576                //get the NXentry node name
2577                HDF5ListGroup /TYPE=1 fileID, "/"
2578                //remove trailing ; from S_HDF5ListGroup
2579                NXentry_name = S_HDF5ListGroup
2580                NXentry_name = ReplaceString(";",NXentry_name,"")
2581                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
2582                        err = 1
2583                        abort "More than one entry under the root node. Ambiguous"
2584                endif
2585                //concatenate NXentry node name and groupName   
2586                groupName = "/" + NXentry_name + groupName
2587                HDF5OpenGroup /Z fileID , groupName, groupID
2588
2589        //      !! At the moment, there is no entry for sample thickness in our data file
2590        //      therefore create new HDF5 group to enable write / patch command
2591        //      comment out the following group creation once thickness appears in revised file
2592       
2593                if(!groupID)
2594                        HDF5CreateGroup /Z fileID, groupName, groupID
2595                        //err = 1
2596                        //abort "HDF5 group does not exist"
2597                else
2598                        // get attributes and save them
2599                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
2600                        //Wave attributes = S_HDF5ListAttributes
2601                endif
2602       
2603                HDF5SaveData /O /Z /IGOR=0  wav, groupID, varName
2604                if (V_flag != 0)
2605                        err = 1
2606                        abort "Cannot save wave to HDF5 dataset" + varName
2607                endif   
2608               
2609                //HDF5SaveData /O /Z /IGOR=0 /A=attributes groupID, varName
2610                //if (V_flag != 0)
2611                ////    err = 1
2612                //      abort "Cannot save attributes to HDF5 dataset"
2613                //endif
2614        catch
2615
2616        endtry
2617       
2618        if(groupID)
2619                HDF5CloseGroup /Z groupID
2620        endif
2621       
2622        if(fileID)
2623                HDF5CloseFile /Z fileID
2624        endif
2625
2626        setDataFolder $cDF
2627        return err
2628end
2629
2630Function DoEdgeCorrection(type)
2631        String type
2632        variable err = 0
2633       
2634        WAVE typeData=$("root:Packages:NIST:"+type+":data")
2635       
2636        //nha workaround for high counts on edges
2637        //copy second column to first column
2638        typeData[][0] = typeData[p][1]
2639        //copy second last column to last column
2640        typeData[][191] = typeData[p][190]
2641        //copy second row to first row
2642        typeData[0][] = typeData[1][q]
2643        //copy second last row to last row
2644        typeData[191][] = typeData[190][q]
2645       
2646        return err     
2647end
2648
2649////// OCT 2009, facility specific bits from ProDiv()
2650//"type" is the data folder that has the corrected, patched, and normalized DIV data array
2651//
2652// the header of this file is rather unimportant. Filling in a title at least would be helpful/
2653//
2654Function Write_DIV_File(type)
2655        String type
2656       
2657        // Your file writing function here. Don't try to duplicate the VAX binary format...
2658        WriteHeaderAndWork(type)
2659       
2660        return(0)
2661End
2662
2663////// OCT 2009, facility specific bits from MonteCarlo functions()
2664//"type" is the data folder that has the data array that is to be (re)written as a full
2665// data file, as if it was a raw data file
2666//
2667// not really necessary
2668//
2669Function/S Write_RawData_File(type,fullpath,dialog)
2670        String type,fullpath
2671        Variable dialog         //=1 will present dialog for name
2672       
2673        // Your file writing function here. Don't try to duplicate the VAX binary format...
2674        //print "not implemented: Write_RawData_File"
2675       
2676        return(fullpath)
2677End
Note: See TracBrowser for help on using the repository browser.