source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/HFIR_DataReadWrite.ipf @ 795

Last change on this file since 795 was 795, checked in by srkline, 11 years ago

Changes to SANS reduction that apply to other Facilities:

These changes are related to the propagation of errors in 2D, on a
per-pixel basis. These changes only affect the errors that are reported in
the QxQy? ASCII file output. The 1D code is unaffected.

If these changes are not implemented, then errors of zero will be substitued as defaults
for these experimental errors.

Upon data loading, an error matrix, linear_data_error is generated and filled with
error values appropriate for Poisson statistics (not simply sqrt(n)).

4 functions in FACILITY_DataReadWrite.ipf have been added, and they are rather
self-explanatory:

In FACILITY_Utils.ipf, the AttenuatorTransmission?() function now returns
an additional parameter, atten_err, which is one standard deviation of the
attenuator transmission value. It returns a default error=0 (which is
correct if no attenuation is used). Facilities can fill this function in
with their own estimates for the uncertainty in the attenutator transmission.

File size: 58.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
4
5//*************************************************************************************************
6//
7// Vers. ????
8// Vers. ???? - branched from main reduction to split out facility
9//                     specific calls
10//
11///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
12//                                      NIST CNR Igor Pro Data Reduction Package
13//                                 HFIR SANS version for SPICE raw data format:
14//
15//                                              University of Tennessee / NIST
16//                                                         DANSE/SANS
17//                                                              Jun. 2009: JHC
18///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19//
20// - RAW data files are read into the RAW folder - integer data from the detector
21//   is decompressed and given the proper orientation
22// - header information is placed into real,integer, or text waves in the order they appear
23//   in the file header
24//
25// Work data (DIV File) is read into the DIV folder
26//
27//*************************************************************************************************
28
29//simple, main entry procedure that will load a RAW sans data file (not a work file)
30//into the RAW dataFolder. It is up to the calling procedure to display the file
31//
32// called by MainPanel.ipf and ProtocolAsPanel.ipf
33//
34Function LoadRawSANSData(msgStr)
35        String msgStr
36
37        String filename = ""
38
39        //each routine is responsible for checking the current (displayed) data folder
40        //selecting it, and returning to root when done
41        PathInfo/S catPathName          //should set the next dialog to the proper path...
42        //get the filename, then read it in
43        filename = PromptForPath(msgStr)//in SANS_Utils.ipf
44       
45        //check for cancel from dialog
46        if(strlen(filename)==0)
47                //user cancelled, abort
48                SetDataFolder root:
49                DoAlert 0, "No file selected, action aborted"
50                return(1)
51        Endif
52       
53        Variable t1=ticks
54       
55        variable error
56        String errorMsg
57       
58        error=ReadHeaderAndData(filename)       //this is the full Path+file
59
60        if (error < 0)
61                String windowName =""
62                switch(error)                                   // fileID holds the return code; check it
63                        case -1:                       
64                                //errorMsg = filename+ ": \r\t Failed to parse XML..."          //No Alert for this case...
65                                break
66                        case -2:                       
67                                //errorMsg = filename+ ": \r\t Either not found or cannot be opened for reading..."             //No Alert for this case...
68                                break
69                        case -3:
70                                errorMsg =  "\r\t XMLutils needs an upgrade:  http://www.igorexchange.com/project/XMLutils"
71                                break
72                        case -4:
73                                errorMsg = filename+ " ===> Not supported version of xml or SPICE..."   
74                                break
75                endswitch
76                SetDataFolder root:
77                //print "Failed loading", filename, "..."
78                DoAlert 0, errorMsg
79                //Clean up waves...
80                //KillWaves/Z M_listAttr, nsList,W_xmlcontentnodes
81                return(1)               //Do not change.
82        endif
83///***** done by a call to UpdateDisplayInformation()
84//      //the calling macro must change the display type
85//      String/G root:myGlobals:gDataDisplayType="RAW"          //displayed data type is raw
86//     
87//      //data is displayed here
88//      fRawWindowHook()
89        SetDataFolder root:
90       
91        Print "Time to load and display (s) = ",(ticks-t1)/60.15
92        Return(0)               //Do not change.
93End
94
95
96//function that does the guts of reading the binary data file
97//fname is the full path:name;vers required to open the file
98//VAX record markers are skipped as needed
99//VAX data as read in is in compressed I*2 format, and is decompressed
100//immediately after being read in. The final root:RAW:data wave is the real
101//neutron counts and can be directly operated on
102//
103// header information is put into three waves: integersRead, realsRead, and textRead
104// logicals in the header are currently skipped, since they are no use in the
105// data reduction process.
106//
107// The output is the three R/T/I waves that are filled at least with minimal values
108// and the detector data loaded into an array named "data"
109//
110// see documentation for the expected information in each element of the R/T/I waves
111// and the minimum set of information. These waves can be increased in length so that
112// more information can be accessed as needed (propagating changes...)
113//
114// called by multiple .ipfs (when the file name is known)
115//
116Function ReadHeaderAndData(filename)
117        String filename
118       
119        String curPath = "root:Packages:NIST:RAW:"     
120        //***NOTE ****
121        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
122        // this read routine, after the open dialog is presented
123        // the "--read" waves end up in the correct folder, but the data does not! Why?
124        //must re-set data folder before writing data array (done below)
125        SetDataFolder curPath   
126        //full filename and path is now passed in...
127        //actually open the file
128        //Open/R refNum as fname
129        STRING/G errorMsg       
130        Variable refNum,t1=ticks
131        //print "Loading", filename, "..."     
132        if (stringmatch(filename,"*.xml") <1)
133                //print "\r  ==> Failed: Not a *.xml file."
134                return (-1)                             //Not *.xml. Do nothing...
135        endif
136        //actually open the file
137        refNum = XmlOpenFile(filename) 
138        if (refNum < 0)
139                XmlCloseFile(refNum,0)
140                //print "\r  ==> Failed: Not a standard xml file format."
141                return (-2)                             //Not a xml file. Do nothing...
142        endif
143       
144        /////////////////////////////////////////////////////////////////////////////////////////////////\/\/\/\/ from P. R. Jemian     
145        //      test to see if XMLutils has the needed upgrade
146        XMLlistXpath(refNum, "/*", "") 
147        IF ( EXISTS( "M_listXPath" ) == 0 )
148                XmlCloseFile(refNum,0)
149                //errorMsg = "XMLutils needs an upgrade:  http://www.igorexchange.com/project/XMLutils"
150       
151                SetDataFolder root:
152                RETURN(-3)                                              // XOPutils needs an upgrade
153        ENDIF
154        ///////////////////////////////////////////////////////////////////////////////////////////////\/\/\/\ from P. R. Jemian
155       
156        // Check if  it is the SPICE version = 1.1
157        String ns_ver = "1.1"
158        Variable ns = 0
159        ns = str2num(XMLstrFmXpath(refNum, "//SPICErack/@SPICE_version","",""))
160       
161        // older version       
162        if (ns <1.1)
163                //errorMsg = filename + ": This SPICE version is not supported"
164                XmlCloseFile(refNum,0)
165                SetDataFolder root:
166                return (-4)
167        endif
168       
169        //this function is for reading in RAW data only, so it will always put data in RAW folder
170       
171        String curFolder="RAW"
172        SetDataFolder curPath           //use the full path, so it will always work
173        Variable/G root:Packages:NIST:RAW:gIsLogScale = 0               //initial state is linear, keep this in RAW folder
174        Variable integer,realval
175        String sansfname,textstr
176       
177        Make/O/N=23 $"root:Packages:NIST:RAW:IntegersRead"
178        Make/O/N=52 $"root:Packages:NIST:RAW:RealsRead"
179        Make/O/T/N=11 $"root:Packages:NIST:RAW:TextRead"
180       
181        Wave intw=$"root:Packages:NIST:RAW:IntegersRead"
182        Wave realw=$"root:Packages:NIST:RAW:RealsRead"
183        Wave/T textw=$"root:Packages:NIST:RAW:TextRead"
184       
185        //Make/O/N=16384 $"root:Pacakges:NIST:RAW:data"
186        //WAVE data=$"root:Packages:NIST:RAW:data"
187       
188        //intw = 0
189        //realw = 0
190        //textw = ""
191       
192       
193        //Redimension/N=(192,192) data                  //NIST raw data is 128x128 - do not generalize
194        //data =0
195       
196        //ORNL HFIR SANS DATA
197        String tempheadhfir =""
198       ReadHFIRSansRaw(refNum,curFolder,tempheadhfir)
199
200       //Take the file name from "actual file name", not from the header: (JC found some cases that those are different.)
201       //This  can be removed where the problem is solved....
202       textw[0]=GetFName(filename,  1)
203
204        SetDataFolder curPath
205        String/G fileList = textw[0]
206        //return the data folder to root
207       
208        WAVE data=$"root:Packages:NIST:RAW:data"
209        Duplicate/O data linear_data                    // data is "fresh" and linear scale, so copy it now
210               
211        // proper error for counting statistics, good for low count values too
212        // rather than just sqrt(n)
213        // see N. Gehrels, Astrophys. J., 303 (1986) 336-346, equation (7)
214        // for S = 1 in eq (7), this corresponds to one sigma error bars
215        Duplicate/O linear_data linear_data_error
216        linear_data_error = 1 + sqrt(linear_data + 0.75)                               
217        //
218       
219        SetDataFolder root:
220
221        Return 0
222
223End
224
225
226//****************
227//main entry procedure for reading a "WORK.DIV" file
228//displays a quick image of the  file, to check that it's correct
229//data is deposited in root:DIV data folder
230//
231// local, currently unused
232//
233//
234
235Proc ReadWork_DIV()
236       
237        String fname = PromptForPath("Select detector sensitivity file")
238        ReadHeaderAndWork("DIV",fname)          //puts what is read in work.div
239       
240        String waveStr = "root:Packages:NIST:DIV:data"
241        NewImage/F/K=1/S=2 $waveStr             //this is an experimental IGOR operation
242        ModifyImage '' ctab= {*,*,YellowHot,0}
243
244        String/G root:Packages:NIST:DIV:fileList = "WORK.DIV"
245       
246        SetDataFolder root:             //(redundant)
247End
248
249
250//this function is the guts of reading a binary VAX file of real (4-byte) values
251// (i.e. a WORK.aaa file)
252// work files have the same header structure as RAW SANS data, just with
253//different data (real, rather than compressed integer data)
254//
255//************
256//this routine incorrectly reads in several data values where the VAX record
257//marker splits the 4-byte real (at alternating record markers)
258//this error seems to not be severe, but shoud be corrected (at great pain)
259//************
260//
261// called from ProtocolAsPanel.ipf
262//
263//
264Function ReadHeaderAndWork(type,fname)
265        String type,fname
266       
267        //type is the desired folder to read the workfile to
268        //this data will NOT be automatically displayed gDataDisplayType is unchanged
269
270//      SVAR cur_folder=root:myGlobals:gDataDisplayType
271        String cur_folder = type
272        String curPath = "root:Packages:NIST:"+cur_folder
273        SetDataFolder curPath           //use the full path, so it will always work
274       
275        Variable refNum,integer,realval
276        String sansfname,textstr
277        Variable/G $(curPath + ":gIsLogScale") = 0              //initial state is linear, keep this in DIV folder
278       
279        Make/O/N=23 $(curPath + ":IntegersRead")
280        Make/O/N=52 $(curPath + ":RealsRead")
281        Make/O/T/N=11 $(curPath + ":TextRead")
282       
283        WAVE intw=$(curPath + ":IntegersRead")
284        WAVE realw=$(curPath + ":RealsRead")
285        WAVE/T textw=$(curPath + ":TextRead")
286       
287        //***NOTE ****
288        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
289        // this read routine, after the open dialog is presented
290        // the "--read" waves end up in the correct folder, but the data does not! Why?
291        //must re-set data folder before writing data array (done below)
292       
293        SetDataFolder curPath
294        if (stringmatch(fname,"*.xml") <1)
295                return 0                                //Not *.xml. Do nothing...
296        endif
297        //actually open the file
298        refNum = XmlOpenFile(fname)     
299        if (refNum < 0)
300                XMLclosefile(refNum, 0)
301                return 0                                //Not a xml file. Do nothing...
302        endif
303       
304        //ORNL HFIR SANS DATA
305        String tempheadhfir =""
306       ReadHFIRSansRaw(refNum,cur_folder,tempheadhfir)
307
308        //Take the file name from "actual file name", not from the header: (JC found some cases that those are different.)
309       //This  can be removed where the problem is solved....
310       textw[0]=GetFName(fname,  1)
311       
312        //keep a string with the filename in the DIV folder
313        String/G $(curPath + ":fileList") = textw[0]
314
315        WAVE data=$"root:Packages:NIST:RAW:data"
316        Duplicate/O data $"root:Packages:NIST:RAW:linear_data"                  // data is "fresh" and linear scale, so copy it now
317       
318        //return the data folder to root
319        SetDataFolder root:
320        Return(0)
321End
322
323/////   ASC FORMAT READER  //////
324/////   FOR WORKFILE MATH PANEL //////
325
326//function to read in the ASC output of SANS reduction
327// currently the file has 20 header lines, followed by a single column
328// of 16384 values, Data is written by row, starting with Y=1 and X=(1->128)
329//
330//returns 0 if read was ok
331//returns 1 if there was an error
332//
333// called by WorkFileUtils.ipf
334//
335Function ReadASCData(fname,destPath)
336        String fname, destPath
337        //this function is for reading in ASCII data so put data in user-specified folder
338        SetDataFolder "root:"+destPath
339
340        NVAR pixelsX = root:myGlobals:gNPixelsX
341        NVAR pixelsY = root:myGlobals:gNPixelsY
342        Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20
343        String str=""
344        //data is initially linear scale
345        Variable/G :gIsLogScale=0
346        Make/O/T/N=(numHdrLines) hdrLines
347        Make/O/D/N=(pixelsX*pixelsY) data                       //,linear_data
348       
349        //full filename and path is now passed in...
350        //actually open the file
351//      SetDataFolder destPath
352        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
353        if(refnum==0)           //FNF error, get out
354                DoAlert 0,"Could not find file: "+fname
355                Close/A
356                SetDataFolder root:
357                return(1)
358        endif
359        if(V_flag!=0)
360                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
361                Close/A
362                SetDataFolder root:
363                return(1)
364        Endif
365        //
366        for(ii=0;ii<numHdrLines;ii+=1)          //read (or skip) 18 header lines
367                FReadLine refnum,str
368                hdrLines[ii]=str
369        endfor
370        //     
371        Close refnum
372       
373//      SetDataFolder destPath
374        LoadWave/Q/G/D/N=temp fName
375        Wave/Z temp0=temp0
376        data=temp0
377        Redimension/N=(pixelsX,pixelsY) data            //,linear_data
378
379        Duplicate/O data linear_data_error
380        linear_data_error = 1 + sqrt(data + 0.75)
381       
382        //just in case there are odd inputs to this, like negative intensities
383        WaveStats/Q linear_data_error
384        linear_data_error = numtype(linear_data_error[p]) == 0 ? linear_data_error[p] : V_avg
385        linear_data_error = linear_data_error[p] != 0 ? linear_data_error[p] : V_avg
386               
387        //linear_data = data
388       
389        KillWaves/Z temp0
390        Close/A
391        //return the data folder to root
392        SetDataFolder root:
393       
394        Return(0)
395End
396
397// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
398// pay attention to what is/not to be trusted due to "fake" information.
399// uses what it can from the header lines from the ASC file (hdrLines wave)
400//
401// destFolder is of the form "myGlobals:WorkMath:AAA"
402//
403//
404// called by WorkFileUtils.ipf
405//
406Function FillFakeHeader_ASC(destFolder)
407        String destFolder
408        Make/O/N=23 $("root:"+destFolder+":IntegersRead")
409        Make/O/N=52 $("root:"+destFolder+":RealsRead")
410        Make/O/T/N=11 $("root:"+destFolder+":TextRead")
411       
412        Wave intw=$("root:"+destFolder+":IntegersRead")
413        Wave realw=$("root:"+destFolder+":RealsRead")
414        Wave/T textw=$("root:"+destFolder+":TextRead")
415       
416        //Put in appropriate "fake" values
417        //parse values as needed from headerLines
418        Wave/T hdr=$("root:"+destFolder+":hdrLines")
419        Variable monCt,lam,offset,sdd,trans,thick
420        Variable xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam
421        String detTyp=""
422        String tempStr="",formatStr="",junkStr=""
423        formatStr = "%g %g %g %g %g %g"
424        tempStr=hdr[3]
425        sscanf tempStr, formatStr, monCt,lam,offset,sdd,trans,thick
426//      Print monCt,lam,offset,sdd,trans,thick,avStr,step
427        formatStr = "%g %g %g %g %g %g %g %s"
428        tempStr=hdr[5]
429        sscanf tempStr,formatStr,xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
430//      Print xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
431       
432        realw[16]=xCtr          //xCtr(pixels)
433        realw[17]=yCtr  //yCtr (pixels)
434        realw[18]=sdd           //SDD (m)
435        realw[26]=lam           //wavelength (A)
436        //
437        // necessary values
438        realw[10]=5                     //detector calibration constants, needed for averaging
439        realw[11]=10000
440        realw[12]=0
441        realw[13]=5
442        realw[14]=10000
443        realw[15]=0
444        //
445        // used in the resolution calculation, ONLY here to keep the routine from crashing
446        realw[20]=65            //det size
447        realw[27]=dlam  //delta lambda
448        realw[21]=bsDiam        //BS size
449        realw[23]=a1            //A1
450        realw[24]=a2    //A2
451        realw[25]=a1a2Dist      //A1A2 distance
452        realw[4]=trans          //trans
453        realw[3]=0              //atten
454        realw[5]=thick          //thick
455        //
456        //
457        realw[0]=monCt          //def mon cts
458
459        // fake values to get valid deadtime and detector constants
460        //
461        textw[9]=detTyp+"  "            //6 characters 4+2 spaces
462        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
463       
464        //set the string values
465        formatStr="FILE: %s CREATED: %s"
466        sscanf hdr[0],formatStr,tempStr,junkStr
467
468        String/G $("root:"+destFolder+":fileList") = tempStr
469        textw[0] = tempStr              //filename
470        textw[1] = junkStr              //run date-time
471       
472        tempStr = hdr[1]
473        tempStr = tempStr[0,strlen(tempStr)-2]          //clean off the last LF
474
475        textW[6] = tempStr      //sample label
476       
477        return(0)
478End
479
480// read specific bits of information from the header
481// each of these operations MUST take care of open/close on their own
482
483// new, April 2011 for error propagation. fill these in with the facility-
484// specific versions, if desired.
485Function WriteTransmissionErrorToHeader(fname,transErr)
486        String fname
487        Variable transErr
488       
489
490        return(0)
491End
492
493Function WriteBoxCountsErrorToHeader(fname,rel_err)
494        String fname
495        Variable rel_err
496       
497        return(0)
498End
499
500Function getSampleTransError(fname)
501        String fname
502       
503        return(0)
504end
505
506Function getBoxCountsError(fname)
507        String fname
508       
509        return(0)
510end
511
512
513// end April 2011 additions
514
515
516Function/S getStringFromHeader(fname,wantedterm)
517        String fname, wantedterm                                //full path:name, term name
518       
519        String str = ""
520        Variable refNum,i
521       
522        //check the ext.
523        if (stringmatch(fname,"*.xml") <1)
524                //print "Failed: Not a *.xml file."
525                return (str)                            //Not *.xml. Do nothing...
526        endif
527        //actually open the file
528        refNum = XmlOpenFile(fname)     
529        if (refNum < 0)
530                //print "Failed: Not a xml file."
531                XmlCloseFile(refNum,0)
532                return (str)                            //Not a xml file. Do nothing...
533        endif
534
535        //ORNL HFIR SANS strings meta DATA
536        if (stringmatch("*filename",wantedterm)>0)
537                str =GetFName(fname,  1)
538        else
539                str=ReadSFromHHead(refNum,wantedterm)  //Get it from the header.
540       endif
541       
542        //return the data folder to root
543        //SetDataFolder root:
544               
545        return(str)
546End
547
548// file suffix (NCNR data file name specific)
549
550// file suffix (13 characters @ byte 19)
551Function/S getSuffix(fname)
552        String fname
553       
554        return(getStringFromHeader(fname,"//suffix"))           //!!!!!!!!!!!!!!!!!!!!!!!!!
555End
556
557// associated file suffix (for transmission)
558
559Function/S getAssociatedFileSuffix(fname)
560        String fname
561       
562        return(getStringFromHeader(fname,"//assoc_suffix"))             //!!!!!!!!!!!!!!!!!!!!!!!!!
563End
564
565// sample label (60 characters @ byte 98)
566Function/S getSampleLabel(fname)
567        String fname
568       
569        return(getStringFromHeader(fname,"//Header/Scan_Title"))
570End
571
572// file creation date (20 characters @ byte 55)
573Function/S getFileCreationDate(fname)
574        String fname
575 
576        return(getStringFromHeader(fname,"//SPICErack/@start_time"))
577End
578
579// Check if the file is transmission file?
580Function/S getIsTrans(fname)
581        String fname
582        return(getStringFromHeader(fname,"//Header/Transmission"))
583End
584
585// read a single real value with GBLoadWave
586Function getRealValueFromHeader(fname,wantedterm,unit)
587        String fname, wantedterm,unit
588       
589        Variable vresult
590        Variable refNum
591       
592        if (stringmatch(fname,"*.xml") <1)
593                //print "Failed: Not a *.xml file."
594                return 0                                //Not *.xml. Do nothing...
595        endif
596        //actually open the file
597        refNum = XmlOpenFile(fname)     
598        if (refNum < 0)
599                //print "Failed: Not a xml file."
600                return 0                                //Not a xml file. Do nothing...
601        endif
602
603        //ORNL HFIR SANS strings meta DATA
604       vresult=ReadVFromHHead(refNum,wantedterm,unit)
605       
606        return(vresult)
607End
608
609//monitor count is at byte 39
610Function getMonitorCount(fname)
611        String fname
612       
613        return(getRealValueFromHeader(fname,"//Counters/monitor",""))
614end
615
616//saved monitor count is at byte 43
617Function getSavMon(fname)
618        String fname
619       
620        return(getRealValueFromHeader(fname,"//Counters/monitor",""))  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!??
621end
622
623//detector count is at byte 47
624Function getDetCount(fname)
625        String fname
626       
627        return(getRealValueFromHeader(fname,"//Counters/psd",""))   //Need to check!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
628end
629
630//Attenuator number is at byte 51
631Function getAttenNumber(fname)
632        String fname
633       
634        return(getRealValueFromHeader(fname,"//Motor_Positions/attenuation","percent")) //in unit of percents
635end
636
637//transmission is at byte 158
638Function getSampleTrans(fname)
639        String fname
640        return(getRealValueFromHeader(fname,"//Transmission_for_Sample",""))
641end
642
643//box counts are stored at byte 494
644Function getBoxCounts(fname)
645        String fname
646       
647        return(getRealValueFromHeader(fname,"//Box_Counts",""))                 
648end
649
650//whole detector trasmission is at byte 392
651Function getSampleTransWholeDetector(fname)
652        String fname
653       
654        return(getRealValueFromHeader(fname,"//Counters/detector","")) //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
655end
656
657//SampleThickness is at byte 162
658Function getSampleThickness(fname)
659        String fname
660       
661        return(getRealValueFromHeader(fname,"//Header/Sample_Thickness","cm"))
662end
663
664//Sample Rotation Angle is at byte 170
665Function getSampleRotationAngle(fname)
666        String fname
667       
668        return(getRealValueFromHeader(fname,"",""))                     //ToDo: define this...
669end
670
671//temperature is at byte 186
672Function getTemperature(fname)
673        String fname
674       
675        return(getRealValueFromHeader(fname,"//Parameter_Positions/tsample","C"))   
676end
677
678//field strength is at byte 190
679Function getFieldStrength(fname)
680        String fname
681       
682        return(getRealValueFromHeader(fname,"//magnetic_field","G"))
683end
684
685//beam xPos is at byte 252
686Function getBeamXPos(fname)
687        String fname
688       
689        return(getRealValueFromHeader(fname,"//Header/beam_center_x_pixel",""))
690end
691
692//beam Y pos is at byte 256
693Function getBeamYPos(fname)
694        String fname
695       
696        return(getRealValueFromHeader(fname,"//Header/beam_center_y_pixel",""))
697end
698
699//sample to detector distance is at byte 260
700Function getSDD(fname)
701        String fname
702       
703        return(getRealValueFromHeader(fname,"//Motor_Positions/sample_det_dist","m"))
704end
705
706//detector offset is at byte 264
707Function getDetectorOffset(fname)
708        String fname
709       
710        return(getRealValueFromHeader(fname,"//Motor_Positions/detector_trans","cm"))  //cm:  HFIR mm
711end
712
713//Beamstop diameter is at byte 272
714Function getBSDiameter(fname)
715        String fname
716       
717        return(getRealValueFromHeader(fname,"//Motor_Positions/beam_trap_size","mm"))  //check if this beamstop diameter?
718end
719
720//source aperture diameter is at byte 280
721Function getSourceApertureDiam(fname)
722        String fname
723       
724        return(getRealValueFromHeader(fname,"//Header/source_aperture_size","mm"))
725end
726
727//sample aperture diameter is at byte 284
728Function getSampleApertureDiam(fname)
729        String fname
730       
731        return(getRealValueFromHeader(fname,"//Header/sample_aperture_size","mm"))
732end
733
734//source AP to Sample AP distance is at byte 288
735Function getSourceToSampleDist(fname)
736        String fname
737       
738        return(getRealValueFromHeader(fname,"//Header/source_distance","m")) //unit=m   :hfir = mm
739end
740
741//wavelength is at byte 292
742Function getWavelength(fname)
743        String fname
744       
745        return(getRealValueFromHeader(fname,"//Header/wavelength", "A"))
746end
747
748//wavelength spread is at byte 296
749Function getWavelengthSpread(fname)
750        String fname
751       
752        return(getRealValueFromHeader(fname,"//Header/wavelength_spread",""))
753end
754
755//transmission detector count is at byte 388
756Function getTransDetectorCounts(fname)
757        String fname
758       
759        return(getRealValueFromHeader(fname,"",""))  // (Unused, return 0)
760end
761
762//detector pixel X size is at byte 220
763Function getDetectorPixelXSize(fname)
764        String fname
765       
766        return(getRealValueFromHeader(fname,"//Header/x_mm_per_pixel","mm"))
767end
768
769//detector pixel Y size is at byte 232
770Function getDetectorPixelYSize(fname)
771        String fname
772       
773        return(getRealValueFromHeader(fname,"//Header/y_mm_per_pixel","mm"))
774end
775
776//total count time is at byte 31       
777Function getCountTime(fname)
778        String fname
779        Variable mtime
780       
781        mtime = getRealValueFromHeader(fname,"//Counters/time","")
782        if (mtime == 0)
783                mtime = 1               //get rid of a singular for calculating a rate in case.
784        endif
785        return(mtime)
786end
787
788//////  integer values
789//////Not used !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
790Function getIntegerFromHeader(fname,wanted)   ///Not used !!!!!!!!!
791        String fname                            //full path:name
792        String wanted           //starting byte
793
794        Variable refNum                                                               
795        Variable vresult
796       
797        if (stringmatch(fname,"*.xml") <1)
798                //print "Failed: Not a *.xml file."
799                return 0                                //Not *.xml. Do nothing...
800        endif
801        //actually open the file
802        refNum = XmlOpenFile(fname)
803        XMLclosefile(refNum, 0)
804        if (refNum < 0)
805                //print "Failed: Not a xml file."
806                return 0                                //Not a xml file. Do nothing...
807        endif
808
809        //ORNL HFIR SANS strings meta DATA
810       vresult=ReadVFromHHead(refNum,wanted, "")
811               
812        return(0)
813End
814//////////////////////////////////////////////////////////////////////////////////
815
816//reads the wavelength from a reduced data file (not very reliable)
817// - does not work with NSORTed files
818// - only used in FIT/RPA (which itself is almost NEVER used...)
819//
820Function GetLambdaFromReducedData(tempName)
821        String tempName
822       
823        String junkString
824        Variable lambdaFromFile, fileVar, junkVal
825        lambdaFromFile = 6.0
826
827        Open/R/P=catPathName fileVar as tempName
828        FReadLine fileVar, junkString
829        FReadLine fileVar, junkString
830        FReadLine fileVar, junkString
831        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
832                FReadLine/N=11 fileVar, junkString
833                FReadLine/N=10 fileVar, junkString
834                sscanf  junkString, "%f",junkVal
835
836                lambdaFromFile = junkVal
837        endif
838        Close fileVar
839       
840        return(lambdaFromFile)
841End
842
843/////   TRANSMISSION RELATED FUNCTIONS    ////////
844//box coordinate are returned by reference
845//
846// box to sum over is bounded (x1,y1) to (x2,y2)
847//
848// this function returns the bounding coordinates as stored in
849// the header
850//
851// if not using the NCNR Transmission module, this function default to
852// returning 0000, and no changes needed
853Function getXYBoxFromFile(fname,x1,x2,y1,y2)
854        String fname
855        Variable &x1,&x2,&y1,&y2
856       
857        Variable refnum
858        String tmpFile = FindValidFilename(fname)
859        // tmpFile is only a parital path
860       
861        // return your bounding box coordinates or default values of 0
862        x1=getRealValueFromHeader(fname,"//XYBox_x1","")
863        x2=getRealValueFromHeader(fname,"//XYBox_x2","")
864        y1=getRealValueFromHeader(fname,"//XYBox_y1","")
865        y2=getRealValueFromHeader(fname,"//XYBox_y2","")
866       
867        if (x1 == -1 || x2 == -1 || y1 == -1 || y2 == -1)
868                x1 = 0
869                x2 = 0
870                y1 = 0
871                y2 = 0
872        endif
873       
874        return(0)
875End
876
877// Writes the coordinates of the box to the header after user input
878//
879// box to sum over bounded (x1,y1) to (x2,y2)
880//
881// if not using the NCNR Transmission module, this function is null
882Function WriteXYBoxToHeader(fname,x1,x2,y1,y2)
883        String fname
884        Variable x1,x2,y1,y2
885       
886        // your code to write bounding box to the header, or nothing
887        String x1str = "", x2str = "", y1str = "", y2str = ""
888        sprintf x1str, "%d", x1
889        sprintf x2str, "%d", x2
890        sprintf y1str, "%d", y1
891        sprintf y2str, "%d", y2
892
893        WriteHFIRHead(fname,x1str,"/SPICErack/XYBox_x1" ,"")   
894        WriteHFIRHead(fname,x2str,"/SPICErack/XYBox_x2" ,"")
895        WriteHFIRHead(fname,y1str,"/SPICErack/XYBox_y1" ,"")
896        WriteHFIRHead(fname,y2str,"/SPICErack/XYBox_y2" ,"")
897       
898        return(0)
899End
900
901// for transmission calculation, writes an NCNR-specific alphanumeric identifier
902// (suffix of the data file)
903//
904Function WriteAssocFileSuffixToHeader(fname,suffix)
905        String fname,suffix
906               
907       
908        WriteHFIRHead(fname,suffix,"/SPICErack/assoc_suffix" ,"text")
909        return(0)
910end
911
912
913//// ==================================================================
914//Keep these functions in case NIST changes: We need these...
915// TrimWhiteSpace (code from Jon Tischler)
916Function/T   HFIR_TrimWS(strg)
917   
918   String strg
919   return HFIR_TrimWSL(HFIR_TrimWSR(strg))
920End
921
922Function/T   HFIR_TrimWSL(strg)
923    String strg
924    Variable i, N=strlen(strg)
925    for (i=0;char2num(strg[i])<=32 && i<N;i+=1)    // find first non-white space
926    endfor
927    return strg[i,Inf]
928End
929
930Function/T   HFIR_TrimWSR(strg)
931    String strg
932    Variable i
933    for (i=strlen(strg)-1; char2num(strg[i])<=32 && i>=0; i-=1)    // find last non-white space
934   endfor
935    return strg[0,i]
936End
937//// ==================================================================
938
939Function ReadHFIRRaw(refNum,prtname,pname)   //NOT USED!!!!!!!!
940        Variable refNum
941        String pname, prtname
942       
943        //temp list of ns
944        MAKE/T/N=(1)/O nsList
945        nsList[0] = "1.1"
946       
947        // Check if  it is the SPICE version = 1.1
948        Variable  item,i
949        String thislocation, ns=""
950        Variable nns
951
952        for (item = 0; item < DimSize(nsList, 0); item += 1)            // loop over all possible namespaces
953                XMLlistAttr(refNum, prtname, nsList[item])
954                wave/T M_listAttr
955       
956                for (i = 0; i < DimSize(M_listAttr,0); i+=1)                    // loop over all available attributes
957                        // Expect the required hfir XML header (will fail if "schemalocation" is not found)
958                        if ( CmpStr(  LowerStr(M_listAttr[i][1]),  LowerStr(pname) ) == 0 )
959                                thisLocation = HFIR_TrimWS(M_listAttr[i][2])
960                                if ( StringMatch(thisLocation, nsList[item] + "*") )
961                                        ns = nsList[item]
962                                        Break
963                                endif
964                        endif
965                endfor
966                if (strlen(ns))
967                        Break           
968                endif
969        endfor
970        sscanf ns,"%f",nns
971return nns
972END
973
974
975////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
976//       Read ORNL HFIR SANS data ( xml format) file:general loading from display raw data
977////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
978Function ReadHFIRSansRaw(refNum,curFolder,tempheadhfir)
979    Variable refNum
980    String curFolder,tempheadhfir
981     
982        String curPath="root:Packages:NIST:"+curFolder
983        SetDataFolder curPath
984        Make/O/N=23 $(curPath+":IntegersRead")
985        Make/O/N=52 $(curPath+":RealsRead")
986        Make/O/T/N=11 $(curPath+":TextRead")
987       
988        Wave intw=$(curPath+":IntegersRead")
989        Wave realw=$(curPath+":RealsRead")
990        Wave/T textw=$(curPath+":TextRead")
991       
992        Variable ind,i,j,centerdata=1
993        Variable pixnumx=0,pixnumy=0
994        String val = "", pix_num = ""// numerical and text values
995        Variable value = 0.0,t1=ticks
996        String unitstr =""      //unit string
997
998        //Initialize wave values         
999         realw=0
1000         intw=0
1001         textw=""
1002         textw[2]=curFolder
1003         textw[3]=""
1004         textw[4]="C"                                ///???
1005         textw[7]="C"                        // temperature unit C
1006         textw[10]="xml"                        //HFIR SANS RAW data file extension
1007         realw[4]  = 1                          //Default for transmission for sample
1008         realw[12]=0.00                       //following 6 values are for non-linear spatial corrections to a detector (RC timing)
1009         realw[15]=0.00                        // 10 and 13 are the X and Y pixel dimensions,,(11,12 and 13,14 are set to values for a linear response, as from a new Ordela detector)
1010         realw[11]=10000.00                          //nonlinear spatial pix(x) //Do not change unless knowing what you are doing...
1011         realw[14]=10000.00                          //nonlinear spatial pix(y)
1012         // detector physical width (right now assumes square...) (in cm)
1013         // beam stop X-position (motor reading, approximate cm from zero position)
1014         // currently NCNR-specific use to identify transmission measurements
1015         // you return 0
1016         realw[37] = 0
1017         //textw[2]="RAW"      //????
1018 
1019//      Print "Time to list attributes (s) = ",(ticks-t1)/60.15
1020//      Print "Time to list elements (s) = ",(ticks-t1)/60.15
1021
1022        // Get and set the number of pixels from the line just above data.
1023        pix_num = XMLstrFmXpath(refNum,"//Data/Detector/@type","","")
1024        pixnumx=Str2num(StringFromList(0,StringFromList(1,pix_num ,","),"]"))   
1025        pixnumy=Str2num(StringFromList(1,StringFromList(0,pix_num ,","),"["))
1026        Variable/G root:myGlobals:gNPixelsX=pixnumx
1027        Variable/G root:myGlobals:gNPixelsY=pixnumy     
1028        SetDataFolder curPath
1029
1030                        //******Below deleted since HFIR prefers to use <Data type="INT32[xxx,xxx]" for pixnumbers
1031                        //********Leave the following lines in case they change the policy.
1032                        //if (stringmatch(tempheadhfir,"Number_of_X_Pixels")>0)                 
1033                        //      pixnumx=Str2num(val)     
1034                        //      Variable/G root:myGlobals:gNPixelsX=pixnumx     
1035                        //       SetDataFolder curPath
1036                        //elseif  (stringmatch(tempheadhfir,"Number_of_Y_Pixels")>0)
1037                        //      pixnumy=Str2num(val)
1038                        //      Variable/G root:myGlobals:gNPixelsY=pixnumy
1039                        //       SetDataFolder curPath
1040                        // Note for units: If in-unit is null, out will be unity.
1041                        textw[6] = XMLstrFmXpath(refNum,"//Header/Scan_Title","","")
1042               
1043                        textw[3] = XMLstrFmXpath(refNum,"//Header/Users","","")         //ToDo: Define   
1044                               
1045                        textw[9] = XMLstrFmXpath(refNum,"//Header/Instrument","","")                            //ToDo: Define
1046                       
1047                        value = ValfromUnit(refNum,"//Transmission_for_Sample","")
1048                        if (value <= 0)
1049                                value = 1               //HFIR default = -1 while NIST package not working if it is <=0: Set default =1. <=NOT good!!!
1050                        endif
1051                        realw[4] = value
1052                       
1053                        realw[3] = ValfromUnit(refNum,"//Motor_Positions/attenuation","percent")
1054                        realw[8] = ValfromUnit(refNum,"//Parameter_Positions/tsample","C")
1055                        realw[0] = ValfromUnit(refNum,"//Counters/monitor","")
1056                        realw[5] = ValfromUnit(refNum,"//Header/Sample_Thickness","cm")
1057                        realw[2] = ValfromUnit(refNum,"//Counters/psd","")       ////Need to check!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1058                        realw[10] = ValfromUnit(refNum,"//Header/x_mm_per_pixel","mm") 
1059                        realw[13] = ValfromUnit(refNum,"//Header/y_mm_per_pixel","mm") 
1060                        Variable/G root:myGlobals:PixelResDefault = unit_convert(realw[13],"mm","cm") //back to cm unit for this default value??!!
1061                        SetDataFolder curPath
1062                       
1063                        realw[16] = ValfromUnit(refNum,"//Header/beam_center_x_pixel","") 
1064                        realw[17] = ValfromUnit(refNum,"//Header/beam_center_y_pixel","") 
1065                        realw[21] = ValfromUnit(refNum,"//Motor_Positions/beam_trap_size","mm")    //what is different from the beam trap diameter in the file???
1066                        realw[18] = ValfromUnit(refNum,"//Motor_Positions/sample_det_dist","m")
1067                        intw[1]  = ValfromUnit(refNum,"//Counters/time","sec")     //Not supported. Assumed in "sec"
1068                        intw[2] = intw[1] //???
1069                        realw[23]  = ValfromUnit(refNum,"//Header/source_aperture_size","mm")      //diameter???
1070                        realw[24]  = ValfromUnit(refNum,"//Header/sample_aperture_size","mm")      //diameter???
1071                        realw[25]  = ValfromUnit(refNum,"//Header/source_distance","m")         
1072                        realw[26]  = ValfromUnit(refNum,"//Header/wavelength","a")     
1073                        realw[27]  = ValfromUnit(refNum,"//Header/wavelength_spread","")       
1074                       
1075                        //Set pixel numbers
1076                        //SetDataFolder curPath
1077                        NVAR pixnumx1= root:myGlobals:gNPixelsX                     
1078                        NVAR pixnumy1= root:myGlobals:gNPixelsY
1079                        Variable pixnx = pixnumx1, pixny = pixnumy1
1080                        realw[20] = realw[10]*pixnx/10.0                        // physical detector width  in cm  // ToDo: Need to check for ypix size???
1081                       
1082                        //prepare to get data
1083                        Make/O/N=(pixnumx1*pixnumy1) $(curPath+":data")
1084                        WAVE  data=$(curPath+":data")
1085                        //set the globals to the detector dimensions (pixels)
1086                        Redimension/N=(pixnx,pixny) data                        //ORNL pixnums are given from the data file
1087                        Variable intens = 0
1088       
1089                        // Read 2d data
1090                        XMLwaveFmXpath(refNum,"/SPICErack/Data/Detector",""," \t\n\r")
1091                        WAVE/T M_xmlContent
1092                        for (i=0;i<pixnx;i+=1)
1093                                for  (j=0;j<pixny;j+=1)
1094                                        sscanf M_xmlContent[j+i*pixny],"%i", intens
1095                                        data[i][j]=intens
1096                                endfor
1097                        endfor
1098                       
1099
1100                       
1101                        ///////unit test 1/2//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1102                        //if  (stringmatch(tempheadhfir,"Detector")<1 ||stringmatch(tempheadhfir,"data"))
1103                        //      print tempheadhfir+"="+val+"["+unitstr+"]"
1104                        //endif
1105                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1106               
1107
1108
1109          //If the data is a sensitivity data, need to be narmalize so that the average over the detector should be 1.
1110         If (stringmatch(curFolder, "DIV") >0)
1111                //Variable V_avg
1112                 WaveStats/Z/Q data
1113                data /= V_avg
1114          endif
1115                       
1116
1117        //keep a string of the filename in the RAW folder
1118       
1119        Variable strpos
1120               
1121        textw[0] = RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","","") )    //////ShortFileName(RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","","") )  )         // file name
1122        textw[1] =   XMLstrFmXpath(refNum,"//SPICErack/@start_time","","")              //Date and Time
1123        textw[5]=StringFromList(0,textw[1]," ")                                                                         //Date
1124       
1125        //String/G $(curPath+":FileList") = textw[0]
1126       
1127        ///////unit test 2/2//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1128        //SetDataFolder curPath
1129        //print "****** ["+num2str(pixnx)+","+num2str(pixny)+"]*******"
1130        //for (i=0;i<Dimsize(textw,0);i+=1)
1131        //      print "textw["+num2str(i)+"] ="+textw[i]
1132        //endfor
1133        //for (i=0;i<Dimsize(realw,0);i+=1)
1134        //      print "realw["+num2str(i)+"] ="+num2str(realw[i])
1135        //endfor
1136        //for (i=0;i<Dimsize(intw,0);i+=1)
1137        //      print "intw["+num2str(i)+"] ="+num2str(intw[i])
1138        //endfor
1139        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1140        // We have everything from file: Need to close the file soon as possible
1141        XMLclosefile(refNum, 0)
1142        SetDataFolder curPath
1143        Killwaves/Z M_listXPath
1144End
1145
1146/// Get real value in NIST unit ///////////////////////////////////////////////////////////////////////////////////////////////////
1147Function ValfromUnit(refNum,wantedterm,NISTunit)
1148        Variable refNum    //FileID
1149        String wantedterm,NISTunit  //Xpath, value in string, unit from HFIR, unit from NIST
1150       
1151        String val="", unitstr=""
1152        Variable value = 0.0
1153        //SetDataFolder curPath ////????????/
1154       
1155        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1156        unitstr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@units","",""))
1157       
1158        //The units of the source_distance is treated special...
1159        if (stringmatch(wantedterm,"*source_distance")>0 )
1160                if  (strlen(unitstr)==0)
1161                        unitstr = "mm"          //Give mm unit since no unit is provided from the file. ///This needs to be corrected soon!!!!
1162                 endif
1163        endif
1164        //String to double
1165        sscanf val, "%f", value
1166        Variable data
1167        data = unit_convert(value,unitstr,NISTunit)
1168
1169        return data
1170End
1171
1172
1173//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1174//Read Real Values from HFIR data 
1175//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1176Function ReadVFromHHead(refNum,wantedterm,NCunit)
1177      Variable refNum
1178      String wantedterm, NCunit
1179     
1180      Variable vresult=-1  // (wantedterm=="", return -1)
1181        Variable ind=0,i=0, value = 0
1182        String  ntype = ""
1183        String savedDataFolder = GetDataFolder(1)
1184        //Default for transmission rate (between 0 to 1): HFIR not provide this as a Float number???? ==>make one: if exist, read it below.
1185        if (stringmatch(wantedterm,"//Transmission_for_Sample")>0)
1186                vresult=1               
1187        endif
1188       
1189        String unitstr = "", typestr="",tempheadhfir="", val=""
1190
1191        if (stringmatch(wantedterm,"") >0 ) // set zero if wnatedterm is "" ,not defined(eg., rotation angle).
1192                vresult =0
1193                //close here
1194                XMLclosefile(refNum, 0)
1195                return vresult
1196        else
1197                //Find the value,unit, and type of the value: a little ugly but faster...
1198                val =   XMLstrFmXpath(refNum,wantedterm,"","")
1199                unitstr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@units","",""))
1200                typestr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@type","",""))
1201                //close here
1202                XMLclosefile(refNum, 0)
1203        endif
1204       
1205        if   (stringmatch(typestr , "INT*")>0)
1206                ntype = "i"             //INT32
1207        elseif (stringmatch(typestr , "FLOAT*")>0)
1208                ntype ="f"              //FLOAT32
1209        else
1210                ntype ="s"              //TEXT
1211        endif   
1212       
1213        String ustr ="%f"                               //default: float
1214        if (stringmatch(ntype,"i") > 0) //for integer   
1215                ustr = "%d"
1216        endif   
1217                                       
1218        //Special case starts!!!
1219        //No unit found in hfir ("mm") but needs to convert to meters.
1220        //The following 3 lines should be removed once HFIR puts th units on the raw data files.
1221        if (stringmatch(wantedterm,"*source_distance")>0&& strlen(unitstr) ==0)
1222                unitstr = "mm"         
1223        endif
1224        //Special case ends!!!
1225       
1226        //Do NOT use str2num(): will loose many decimal digits.
1227        sscanf val, ustr, value
1228        vresult = unit_convert(value,unitstr,NCunit)
1229        if (stringmatch(wantedterm,"*Transmission_for_Sample")>0 && vresult == 0)
1230                 //Transmission default value if it was set to 0.
1231                 vresult = 1
1232        endif
1233                       
1234        //Set PixResDefault from y_mm_per_pixel (not x_mm_per_pixel!!!!!!!!)
1235        if (stringmatch(wantedterm,"*y_mm_per_pixel")>0)
1236                 Variable/G root:myGlobals:PixelResDefault = unit_convert(vresult,"mm","cm") //back to cm unit for this default value??!!
1237                 SetDataFolder savedDataFolder          //In case...
1238        endif
1239
1240               
1241        return (vresult)
1242
1243End
1244
1245/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1246//Read Strings from HFIR data 
1247/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1248Function/S ReadSFromHHead(refNum,wantedterm)
1249      Variable refNum
1250      String wantedterm
1251     
1252      String tempheadhfir = ""
1253      String result = "",gotterm ="n" ,name
1254        Variable ind,i
1255
1256      if   (stringmatch(wantedterm,"")>0)
1257                result = ""
1258                XMLclosefile(refNum, 0)
1259                return (result)
1260        endif
1261       
1262        result =  XMLstrFmXpath(refNum,wantedterm,"","")
1263        if (stringmatch(result, "") != -1 )     
1264                gotterm ="y"   
1265        endif
1266
1267        //HFIR header does not have "suffix" tag but one can get the info from file name before user writes the tag into the header.
1268        if (stringmatch("",result)>0     && stringmatch("//suffix",wantedterm)>0 )
1269                name = RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","",""))
1270                result=StringFromList(2,StringFromList(0, name,"."), "_")+"_"+StringFromList(3,StringFromList(0,name,"."), "_")
1271        endif
1272
1273        //Close file here.
1274        XMLclosefile(refNum, 0)
1275       
1276        if (stringmatch(gotterm,"n")>0 )
1277                result = ""
1278        endif   
1279
1280      return (result)
1281End
1282
1283
1284//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1285//WRITE Real Values to HFIR data file 
1286//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1287
1288Function WriteHFIRHead(filename,value,wantedterm,NCunit)
1289     
1290      String filename, value,wantedterm, NCunit //where value is a string...
1291     
1292        String valstr
1293      Variable/D vresult = 0
1294      Variable refNum
1295        Variable ind=0,i=0, vals
1296       
1297        Variable typenum = 0
1298        String ntype = ""       //Do not change this initial, "".
1299        String nstr = "/SPICErack"              //to add new nodes and content: NEVER CAHNGE this string
1300        String errorMsg =""
1301       
1302        //print "Loading", filename, "..."
1303        if (stringmatch(filename,"*.xml") <1)
1304                //print "\r  ==>  Failed: Not a *.xml file."
1305                return 0                                //Not *.xml. Do nothing...
1306        endif
1307        //actually open the file
1308        refNum = XmlOpenFile(filename) 
1309
1310        if (refNum < 0)
1311                switch(refNum)                                 
1312                        case -1:
1313                                errorMsg = errorMsg+filename+ "  ==>  Not a standard xml file format; Please check if the file is not broken..."
1314                        break
1315                        case -2:
1316                                errorMsg = errorMsg+filename+"  ==>  Please check if the file name is same as that written in the header..."
1317                        break
1318                endswitch
1319                print errorMsg
1320                XMLclosefile(refNum, 0)
1321                return -1                               //Not a xml file. Do nothing...
1322        endif
1323
1324                String unitstr = "",typestr="", val=""
1325
1326                if  (strlen(wantedterm)==0)     
1327                        vresult =0                              //If input is NULL, do nothing...
1328                        nstr = ""                                       //reset as No new node
1329
1330                else   //(stringmatch(tempheadhfir,wantedterm)>0)       
1331                        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1332               
1333                        //Special case starts!!!
1334                        //No unit founds in hfir ("mm") file but needs to convert to meters. Let's give it one.
1335                        if (stringmatch(wantedterm,"*source_distance")>0&& strlen(unitstr) ==0)
1336                                unitstr = "mm" 
1337                                ntype ="f"     
1338                        //Special case ends!!!
1339                        else
1340                                unitstr =  XMLstrFmXpath(refNum,wantedterm+"/@units","","")
1341                                typestr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@type","",""))
1342       
1343                                ntype ="s"              //TEXT 
1344                               
1345                                        if  (strlen(typestr)==0)
1346                                                ntype = "s"
1347                                        elseif   (stringmatch(typestr, "INT*")>0)
1348                                                ntype = "i"             //INT32
1349                                        elseif (stringmatch(typestr, "FLOAT*")>0)
1350                                                ntype ="f"              //FLOAT32
1351                                        endif   
1352                        endif
1353                       
1354                        if (stringmatch(ntype,"s") > 0) //for strings           
1355                                vresult = 1                     
1356                                valstr =value
1357                        else
1358                                String ustr ="%f"                               //default: float
1359                                if (stringmatch(ntype,"i") > 0) //for integer   
1360                                        ustr = "%d"
1361                                endif                   
1362                                sscanf  value,ustr, vals
1363                                vresult = unit_convert(vals,NCunit,unitstr)     //Unit correction...(back to the HFIR unit)
1364                               
1365                                sprintf valstr,ustr, vresult
1366                        endif
1367                       
1368                        if (stringmatch(wantedterm,"/SPICErack/*")>0&& strlen(val) ==0)
1369                                nstr = "/SPICErack"
1370                                // remove "/SPICErack/" from wantedterm
1371                                wantedterm = StringFromList(2, wantedterm,"/SPICErack/")
1372                        else
1373                                XMLsetNodeStr(refNum,wantedterm,"",valstr)      //to set
1374                                nstr = ""                               //reset as No new node
1375                        endif
1376                        //break
1377                 endif         
1378        //to write new  attr name and value which are not found in the raw file.
1379        if (strlen(nstr)>2)                             
1380                 XMLaddNode(refNum,nstr,"",wantedterm,value,1)
1381                 // nstr to add new node
1382                 nstr = "//"+wantedterm
1383                 // get unit
1384                 if (stringmatch(NCunit,"text")>0)     
1385                        ntype = "text"
1386                        vresult = 1
1387                 else
1388                        XMLsetAttr(refNum,nstr,"","units",NCunit)       //use NIST units.
1389                        ntype = "FLOAT32"                                               //Let's set the any number as float for now... 
1390                        sscanf  value, "%f", vals
1391                        vresult = vals         
1392                 endif
1393                 //print "*** Note:*** \r     *** No parameter named",wantedterm, "was found, so it was added to the end of your data file."
1394                 XMLsetAttr(refNum,nstr,"","type",ntype)       
1395        endif
1396
1397        //KillWaves/Z W_ElementList,M_xmlContent,M_listXPath,M_listAttr                 //clean up
1398        if      (strlen(wantedterm)==0 && vresult == -1)
1399                XMLclosefile(refNum, 0)
1400                //print "Failed writing",wantedterm, "on", filename, "..."
1401        else
1402                XMLclosefile(refNum, 1)                                         //save and close the file.
1403                //print "Finished writing",wantedterm,"=",value,"[",NCunit,"]  on", filename, "..."
1404        endif
1405        return (vresult)
1406
1407End
1408
1409
1410Function UserGetWLPanel_ContButton(cntrlName)
1411      String cntrlName
1412      DoWindow /K WaveLengthInput
1413End
1414
1415Function Daskcheckbox(cntrlName,checked)
1416String cntrlName
1417Variable checked
1418
1419Wave realw=$"root:RAW:RealsRead"
1420Variable/G root:myGlobals:globDask=checked
1421      if (checked==1)
1422           Variable /G root:myGlobals:globwlfix=realw[26]
1423           Variable /G root:myGlobals:globdwlfix=realw[27]
1424      endif
1425
1426 End
1427 
1428 
1429Function Daskcheckbox1(cntrlName,checked)
1430String cntrlName
1431Variable checked
1432
1433Wave templw=$"root:RAW:tempwave1"
1434Variable/G root:myGlobals:globDask1=checked
1435      if (checked==1)
1436           Variable /G root:myGlobals:globwlfix=templw[0]
1437           Variable /G root:myGlobals:globdwlfix=templw[1]
1438      endif
1439
1440 End
1441 
1442//Write whether Transmission is True or False.
1443Function Write_isTransmissionToHeader(fname,str)
1444        String fname,str
1445
1446        WriteHFIRHead(fname,str, "//Header/Transmission","text")       
1447        return(0)
1448End
1449
1450//sample transmission is a real value at byte 158
1451Function WriteTransmissionToHeader(fname,trans)
1452        String fname
1453        Variable trans
1454
1455        String transstr = ""
1456        sprintf transstr, "%f", trans
1457
1458         WriteHFIRHead(fname,transstr,"/SPICErack/Transmission_for_Sample" ,"")                 
1459        return(0)
1460End
1461
1462//whole transmission is a real value at byte 392
1463Function WriteWholeTransToHeader(fname,trans)
1464        String fname
1465        Variable trans
1466
1467        String transstr = ""
1468        sprintf transstr, "%f", trans
1469
1470        WriteHFIRHead(fname,transstr,"//Counters/detector" ,"")         //????????????????????????????????????????????????????????
1471        return(0)
1472End
1473
1474//box sum counts is a real value
1475// used for transmission calculation module
1476//box sum counts is a real value at byte 494
1477Function WriteBoxCountsToHeader(fname,counts)
1478        String fname
1479        Variable counts
1480
1481        String countsstr = ""
1482        sprintf countsstr, "%f", counts
1483
1484        WriteHFIRHead(fname,countsstr,"/SPICErack/Box_Counts" ,"")     
1485        return(0)
1486End
1487
1488//Below units refer to NIST units..
1489//beam stop X-pos is at byte 368
1490Function WriteBSXPosToHeader(fname,xpos)
1491        String fname
1492        Variable xpos
1493
1494        String xposstr = ""
1495        sprintf xposstr, "%f", xpos
1496
1497        WriteHFIRHead(fname,xposstr,"//Motor_Positions/beam_trap_x","mm")       ///Is this diameter?
1498        return(0)
1499End
1500
1501//sample thickness is at byte 162
1502Function WriteThicknessToHeader(fname,num)
1503        String fname
1504        Variable num
1505
1506        String numstr = ""
1507        sprintf numstr, "%f", num
1508
1509        WriteHFIRHead(fname,numstr,"//Header/Sample_Thickness","cm")
1510        return(0)
1511End
1512
1513//beam center X pixel location is at byte 252
1514Function WriteBeamCenterXToHeader(fname,num)
1515        String fname
1516        Variable num
1517
1518        String numstr = ""
1519        sprintf numstr, "%f", num
1520
1521        WriteHFIRHead(fname,numstr,"//Header/beam_center_x_pixel" ,"")
1522        return(0)
1523End
1524
1525//beam center Y pixel location is at byte 256
1526Function WriteBeamCenterYToHeader(fname,num)
1527        String fname
1528        Variable num
1529
1530        String numstr = ""
1531        sprintf numstr, "%f", num
1532
1533        WriteHFIRHead(fname,numstr,"//Header/beam_center_y_pixel","")
1534        return(0)
1535End
1536
1537//Attenuation (percent) 0 for no attanuation (not its transmission)
1538Function WriteAttenNumberToHeader(fname,num)
1539        String fname
1540        Variable num
1541
1542        String numstr = ""
1543        sprintf numstr, "%f", num
1544
1545        WriteHFIRHead(fname,numstr,"//Motor_Positions/attenuation","percent")   // HFIR has attenuation % instead of this. thus user has to use patch unless somebody change the format!!!!
1546        return(0)
1547End
1548
1549//monitor count is at byte 39
1550Function WriteMonitorCountToHeader(fname,num)
1551        String fname
1552        Variable num
1553
1554        String numstr = ""
1555        sprintf numstr, "%f", num
1556
1557        WriteHFIRHead(fname,numstr,"//Counters/monitor","")
1558        return(0)
1559End
1560
1561//total detector count is at byte 47
1562Function WriteDetectorCountToHeader(fname,num)
1563        String fname
1564        Variable num
1565
1566        String numstr = ""
1567        sprintf numstr, "%f", num
1568
1569        WriteHFIRHead(fname,numstr,"//Counters/psd","")
1570        return(0)
1571End
1572
1573//transmission detector count is at byte 388
1574Function WriteTransDetCountToHeader(fname,num)
1575        String fname
1576        Variable num
1577
1578        String numstr = ""
1579        sprintf numstr, "%f", num
1580
1581        WriteHFIRHead(fname,numstr,"//Counters/detector","")   ///Check with Steve & Ken!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1582        return(0)
1583End
1584
1585//wavelength is at byte 292
1586Function WriteWavelengthToHeader(fname,num)
1587        String fname
1588        Variable num
1589
1590        String numstr = ""
1591        sprintf numstr, "%f", num
1592
1593        WriteHFIRHead(fname,numstr,"//Header/wavelength" ,"angstroms")
1594        return(0)
1595End
1596
1597//wavelength spread is at byte 296
1598Function WriteWavelengthDistrToHeader(fname,num)
1599        String fname
1600        Variable num
1601
1602        String numstr = ""
1603        sprintf numstr, "%f", num
1604
1605        WriteHFIRHead(fname,numstr,"//Header/wavelength_spread","")
1606        return(0)
1607End
1608
1609//temperature is at byte 186
1610Function WriteTemperatureToHeader(fname,num)
1611        String fname
1612        Variable num
1613
1614        String numstr = ""
1615        sprintf numstr, "%f", num
1616
1617        WriteHFIRHead(fname,numstr,"//Parameter_Positions/tsample" ,"C")
1618        return(0)
1619End
1620
1621//magnetic field is at byte 190
1622Function WriteMagnFieldToHeader(fname,num)
1623        String fname
1624        Variable num
1625
1626        String numstr = ""
1627        sprintf numstr, "%f", num
1628
1629        WriteHFIRHead(fname,numstr,"/SPICErack/magnetic_field","G")  //Not defined on HFIR file...  Should be changed the name when decided...
1630        return(0)
1631End
1632
1633//Source Aperture diameter is at byte 280
1634Function WriteSourceApDiamToHeader(fname,num)
1635        String fname
1636        Variable num
1637
1638        String numstr = ""
1639        sprintf numstr, "%f", num
1640
1641        WriteHFIRHead(fname,numstr,"//Header/source_aperture_size","mm")
1642        return(0)
1643End
1644
1645//Sample Aperture diameter is at byte 284
1646Function WriteSampleApDiamToHeader(fname,num)
1647        String fname
1648        Variable num
1649
1650        String numstr = ""
1651        sprintf numstr, "%f", num
1652
1653        WriteHFIRHead(fname,numstr,"//Header/sample_aperture_size","mm")
1654        return(0)
1655End
1656
1657//Source to sample distance is at byte 288
1658Function WriteSrcToSamDistToHeader(fname,num)
1659        String fname
1660        Variable num
1661
1662        String numstr = ""
1663        sprintf numstr, "%f", num
1664
1665        WriteHFIRHead(fname,numstr,"//Header/source_distance","m")     //unit=m   :hfir = mm ???????????????
1666        return(0)
1667End
1668
1669//detector offset is at byte 264
1670Function WriteDetectorOffsetToHeader(fname,num)
1671        String fname
1672        Variable num
1673
1674        String numstr = ""
1675        sprintf numstr, "%f", num
1676
1677        WriteHFIRHead(fname,numstr,"//Header/detector_trans","cm")  //cm:  HFIR = mm !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1678        return(0)
1679End
1680
1681//beam stop diameter is at byte 272
1682Function WriteBeamStopDiamToHeader(fname,num)
1683        String fname
1684        Variable num
1685       
1686        String numstr = ""
1687        sprintf numstr, "%f", num
1688       
1689        WriteHFIRHead(fname,numstr,"//Motor_Positions/beam_trap_size","mm")  //check !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1690        return(0)
1691End
1692
1693//sample to detector distance is at byte 260
1694Function WriteSDDToHeader(fname,num)
1695        String fname
1696        Variable num
1697
1698        String numstr = ""
1699        sprintf numstr, "%f", num
1700       
1701        WriteHFIRHead(fname,numstr,"//Motor_Positions/sample_det_dist","m")
1702        return(0)
1703End
1704
1705//detector pixel X size (mm) is at byte 220
1706Function WriteDetPixelXToHeader(fname,num)
1707        String fname
1708        Variable num
1709
1710        String numstr = ""
1711        sprintf numstr, "%f", num
1712       
1713        WriteHFIRHead(fname,numstr, "//Header/x_mm_per_pixel","mm")
1714        return(0)
1715End
1716
1717//detector pixel Y size (mm) is at byte 232
1718Function WriteDetPixelYToHeader(fname,num)
1719        String fname
1720        Variable num
1721       
1722        String numstr = ""
1723        sprintf numstr, "%f", num
1724       
1725        WriteHFIRHead(fname,numstr, "//Header/y_mm_per_pixel","mm")
1726        return(0)
1727End
1728
1729// sample label
1730// limit to 60 characters
1731Function WriteSamLabelToHeader(fname,str)
1732        String fname,str
1733       
1734        if(strlen(str) > 60)
1735                str = str[0,59]
1736        endif
1737        WriteHFIRHead(fname,str, "//Header/Scan_Title","text") //Users tend to put the sample descrpt here instead of "Sample_Name"...
1738        return(0)
1739End
1740
1741
1742Function WriteCountTimeToHeader(fname,num)
1743        String fname
1744        Variable num
1745       
1746        String numstr = ""
1747        sprintf numstr, "%f", num
1748       
1749        WriteHFIRHead(fname,numstr,"//Counters/time","sec")
1750        return(0)
1751End
1752
1753
1754/////Handy Unit converter for length & time units"
1755Function length_unit_convert(from,to)  // input: ("m", cm")==> output=10,....;   input: ("", "") ==> out = 1
1756        String from, to
1757       
1758        Variable i, out
1759       
1760        Make/O/T/N=(18,2) munit
1761       
1762        //ToDo: to combine the same units       
1763        //length units
1764        munit[0][0]="m"   //popular units first...
1765        munit[0][1]= "1"
1766        munit[1][0]="cm"
1767        munit[1][1]= "0.01"
1768        munit[2][0]="mm"
1769        munit[2][1]= "0.001"
1770        munit[3][0]="angstroms"  //HFIR used this rather than A
1771        munit[3][1]= "1e-10"
1772        munit[4][0]="meters"
1773        munit[4][1]= "1"
1774        munit[5][0]="um"
1775        munit[5][1]= "1e-06"
1776        munit[6][0]="nm"
1777        munit[6][1]= "1e-09"
1778        munit[7][0]="km"
1779        munit[7][1]= "1000"
1780        munit[8][0]="a"
1781        munit[8][1]= "1e-10"
1782        munit[9][0]="angstrom"
1783        munit[9][1]= "1e-10"
1784        munit[10][0]="microns"
1785        munit[10][1]= "1e-6"
1786        munit[11][0]="meter"
1787        munit[11][1]= "1"
1788       
1789        //time units
1790        munit[12][0]="sec"
1791        munit[12][1]= "1"
1792        munit[13][0]="seconds"
1793        munit[13][1]= "1"
1794        munit[14][0]="min"
1795        munit[14][1]= "60"
1796        munit[15][0]="minutes"
1797        munit[15][1]= "60"
1798        munit[16][0]="hrs"
1799        munit[16][1]= "3600"
1800        munit[17][0]="hours"
1801        munit[17][1]= "3600"
1802        //Add more units here...
1803         
1804        String  v_from="", v_to=""
1805        for (i = 0; i<DimSize(munit,0); i+=1)
1806                if (stringmatch(munit[i][0],from)>0)  // IgorPro "stringmatch()" function handles both lower & upper cases.
1807                        v_from = munit[i][1]
1808                        break
1809                endif
1810        endfor
1811       
1812        for (i = 0; i<DimSize(munit,0); i+=1)
1813                if (stringmatch(munit[i][0],to)>0)
1814                        v_to = munit[i][1]
1815                        break
1816                endif
1817        endfor
1818       
1819        KillWaves/Z munit
1820       
1821       
1822        if (strlen(v_from)==0 || strlen(v_to) ==0)
1823                out = 1                 //Do nothing...
1824        else
1825                Variable vf, vt
1826                sscanf  v_to, "%f", vt
1827                sscanf  v_from, "%f", vf
1828                out = vf / vt
1829        endif
1830        return out
1831End
1832
1833
1834///For length and temperature units
1835Function unit_convert(val, from,to)  // input: ("m", cm")==> output=10,....;   input: ("", "") ==> out = 1
1836        Variable val
1837        String from, to
1838
1839        from = RemoveAllSpaces(from)
1840        to = RemoveAllSpaces(to)
1841                       
1842        Variable i, out = val
1843
1844        //Search for two same strings, or one with none.
1845        if (stringmatch(from,to)>0 ||strlen(from) == 0||strlen(to)==0)
1846                out = val
1847               
1848        //Temperature unit: support only C and K
1849        elseif (stringmatch(from,"C")>0 || stringmatch(to,"K")>0||stringmatch(to,"C")>0 || stringmatch(from,"K")>0)
1850                out =temp_unit_convert(val, from,to)
1851               
1852        //Length unit                   
1853        else
1854                out = val*length_unit_convert(from,to)                                                 
1855        endif
1856
1857        return out
1858End
1859
1860//temperature unit converter: Only support K and C.
1861Function temp_unit_convert(val, from,to) 
1862        Variable val
1863        String from, to
1864       
1865        Variable i, j, out = val
1866
1867        Make/O/T/N=(2,2) tunit
1868       
1869        tunit[0][0]="C"   //popular units first...
1870        tunit[0][1]= "-273.15"
1871        tunit[1][0]="K"
1872        tunit[1][1]= "0"       
1873
1874        String  v_from="", v_to=""
1875
1876        for (i = 0; i<DimSize(tunit,0); i+=1)
1877                if (stringmatch(tunit[i][0],from)==1)  // IgorPro "stringmatch()" function handles both lower & upper cases.
1878                        v_from = tunit[i][1]
1879                        break
1880                endif
1881        endfor
1882
1883        for (j = 0; j<DimSize(tunit,0); j+=1)
1884                if (stringmatch(tunit[j][0],to)==1)
1885                        v_to = tunit[j][1]
1886                        break
1887                endif   
1888        endfor 
1889        KillWaves/Z tunit
1890        if (strlen(v_from)==0 || strlen(v_to) ==0)
1891                out = 1                 //Do nothing...
1892        else
1893                Variable vt, vf
1894                sscanf  v_to, "%f", vt
1895                sscanf  v_from, "%f", vf
1896                out = val + (vt - vf)
1897        endif
1898        return out
1899End
1900
1901
1902///This function make HFIR SANS data file shorter which is more than 30 characters causing problem taking other names after the file name.
1903//Will remove instrumental name.
1904Function/S ShortFileName(fileName)
1905        String fileName
1906        //Default: just passing
1907        String fname = fileName
1908
1909        //Check whether it is from HiResSANS or BioSANS and remove the head
1910        if (stringmatch(fileName,"HiResSANS_*.*")>0 )
1911                fname = ReplaceString("HiResSANS_",fname,"HS_",0,1)   
1912        elseif (stringmatch(filename,"BioSANS_*.*")>0)
1913                fname = ReplaceString("BioSANS_",fname,"BS_",0,1)     
1914        endif
1915        return fname
1916END
1917
1918//Not used
1919///This function return the original HFIR SANS data file name that was shorten before.
1920//Put them back to HiResSANS*** or BioSANS***.
1921Function/S FullFileName(fname)
1922        String fname
1923        //Default: just passing
1924        String fileName = fname
1925       
1926        //Check whether it is from HiResSANS or BioSANS
1927        if (stringmatch(fname,"*HS_*.*")>0 )
1928                fileName = ReplaceString("HS_",fname,"HiResSANS_",0,1) 
1929        elseif (stringmatch(fname,"*BS_*.*")>0)
1930                fileName = ReplaceString("BS_",fname,"BioSANS_",0,1)   
1931        endif
1932
1933        return fileName
1934END
1935
1936
1937///Find file name from full Path+file
1938Function/S GetFName(path,  length)
1939        String path
1940        Variable length // 1 for full name, 0 for shorten name, others pass the name
1941       
1942        Variable index
1943        String ofname, mfname
1944       
1945        // get index of the file name
1946        index = ItemsInList(path,":") - 1
1947        // get file name
1948        ofname = StringFromList(index,path,":")
1949        //modify the name if need otherwise return w/o change
1950        if (length == 0)
1951                mfname = ShortFileName(ofname)
1952        elseif (length == 1)
1953                mfname = FullFileName(ofname)
1954        else
1955                mfname = ofname
1956        endif
1957        // return the path+modified file name
1958        return mfname
1959End
1960
1961
1962///Find file name from full Path+file and replace file name to a shorter or full name in path+file.
1963Function/S ReplaceFName(path,  length)
1964        String path
1965        Variable length // 1 for full name, 0 for shorten name
1966       
1967        Variable index
1968        String ofname,mfname
1969       
1970        // get index of the file name
1971        index = ItemsInList(path,":") - 1
1972        // get file name
1973        ofname = StringFromList(index,path,":")
1974        //modify the name if need otherwise return w/o change
1975        if (length == 0)
1976                mfname = ShortFileName(ofname)
1977        else
1978                mfname = FullFileName(ofname)
1979        endif
1980        // return the path+modified file name
1981        return ReplaceString(ofname,path,mfname,0,1)
1982End
1983
1984////Unused ///Not working well
1985// Change file name before and after Xml open
1986Function/S XmlFileOpen(fname)
1987        String fname
1988       
1989        // fname = path + full file name
1990        fname = ReplaceFName(fname,  1)
1991        XmlOpenFile(fname)
1992        // path + short file name
1993        return ReplaceFName(fname,  0)
1994End
1995
1996
1997////// OCT 2009, facility specific bits from ProDiv()
1998//"type" is the data folder that has the corrected, patched, and normalized DIV data array
1999//
2000// the header of this file is rather unimportant. Filling in a title at least would be helpful/
2001//
2002Function Write_DIV_File(type)
2003        String type
2004       
2005        // Your file writing function here. Don't try to duplicate the VAX binary format...
2006       
2007        return(0)
2008End
2009
2010////// OCT 2009, facility specific bits from MonteCarlo functions()
2011//"type" is the data folder that has the data array that is to be (re)written as a full
2012// data file, as if it was a raw data file
2013//
2014// not really necessary
2015//
2016Function Write_RawData_File(type,fullpath,dialog)
2017        String type,fullpath
2018        Variable dialog         //=1 will present dialog for name
2019       
2020        // Your file writing function here. Don't try to duplicate the VAX binary format...
2021        Print "Write_RawData_File stub"
2022       
2023        return(0)
2024End
Note: See TracBrowser for help on using the repository browser.