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

Last change on this file since 575 was 572, checked in by srkline, 13 years ago

Merging changes:

NCNR_Utils -> merging these into FACILITY, HFIR, and ILL_Utils

HFIR files merged by hand to reflect JaeHie?'s 29JUL09 version

Changed MainPanel? to look for TISANE or RealTime? functions to prevent button procedures from being called when the procedures aren't there. Seemed easier than separate versions without the buttons. #define at the begining of TISANE.ipf -> #ifdef in MainPanel? didn't work for some reason?

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