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

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

A variety of changes to get some of the basic reduction functions working with HFIR raw data files.

Patch now works correctly without duplicating file names in the popup list.

Transmissions can be assigned and calculated now that I've changed the critera for deciding if a file is a transmission file. Hopefully this will always work - it's based on the beamstop y-position being less than 30 mm for all four beam stops.

When checking for a DIV file, it returns an OK if the extension is .xml, since the raw data and div files can't be distinguished like the binary VAX data.

The file catalog is correct, but still excruciatingly slow.

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