source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_WorkFolderUtils.ipf @ 979

Last change on this file since 979 was 979, checked in by srkline, 7 years ago

more additions to start the work file flow of converting RAW folder to a WORK folder. Raw_to_Work will be the function that sequentially applies the corrections. All corrections can be turned on/off with preferences.

File size: 26.3 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method and strict wave access.
2#pragma version=1.0
3#pragma IgorVersion=6.1
4
5//*******************
6// Vers 1.0 JAN2016
7//
8//*******************
9//  VSANS Utility procedures for handling of workfiles (each is housed in a separate datafolder)
10//
11// - adding RAW data to a workfile
12// -- this conversion applies the detector corrections
13//
14// - copying workfiles to another folder
15//
16// - absolute scaling
17//
18// - (no) the WorkFile Math panel for simple image math (not done - maybe in the future?)
19// -
20// - (no) adding work.drk data without normalizing to monitor counts (the case not currently handled)
21//***************************
22
23//
24// Functions used for manipulation of the local Igor "WORK" folder
25// structure as raw data is displayed and processed.
26//
27//
28Strconstant ksDetectorListNoB = "FT;FB;FL;FR;MT;MB;ML;MR;"
29Strconstant ksDetectorListAll = "FT;FB;FL;FR;MT;MB;ML;MR;B;"
30
31
32//
33//Entry procedure from main panel
34//
35Proc CopyWorkFolder(oldType,newType)
36        String oldType,newType
37        Prompt oldType,"Source WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
38        Prompt newType,"Destination WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
39
40        // data folder "old" will be copied to "new" (either kills/copies or will overwrite)
41        CopyHDFToWorkFolder(oldtype,newtype)
42End
43
44//
45// copy what is needed for data processing (not the DAS_logs)
46// from the RawVSANS storage folder to the local WORK folder as needed
47//
48// TODO -- at what stage do I make copies of data in linear/log forms for data display?
49//                      -- when do I make the 2D error waves?
50//
51// TODO - decide what exactly I need to copy over. May be best to copy all, and delete
52//       what I know that I don't need
53//
54// TODO !!! DuplicateDataFolder will FAIL - in the base case of RAW data files, the
55//  data is actually in use - so it will fail every time. need an alternate solution. in SANS,
56// there are a limited number of waves to carry over, so Dupliate/O is used for rw, tw, data, etc.
57//
58//
59//
60// TODO : I also need a list of what is generated during processing that may be hanging around - that I need to
61//     be sure to get rid of - like the calibration waves, solidAngle, etc.
62//
63// hdfDF is the name only of the data in storage. May be full file name with extension (clean as needed)
64// type is the destination WORK folder for the copy
65//
66Function CopyHDFToWorkFolder(fromStr,toStr)
67        String fromStr,toStr
68       
69        String fromDF, toDF
70       
71        // make the DF paths - source and destination
72        fromDF = "root:Packages:NIST:VSANS:"+fromStr
73        toDF = "root:Packages:NIST:VSANS:"+toStr
74       
75//      // make a copy of the file name for my own use, since it's not in the file
76//      String/G $(toDF+":file_name") = root:
77       
78        // copy the folders
79        KillDataFolder/Z $toDF                  //DuplicateDataFolder will not overwrite, so Kill
80       
81        if(V_flag == 0)         // kill DF was OK
82                DuplicateDataFolder $("root:Packages:NIST:VSANS:"+fromStr),$("root:Packages:NIST:VSANS:"+toStr)
83               
84                // I can delete these if they came along with RAW
85                //   DAS_logs
86                //   top-level copies of data (duplicate links)
87                KillDataFolder/Z $(toDF+":entry:entry:DAS_logs")
88                KillDataFolder/Z $(toDF+":entry:entry:data")
89                KillDataFolder/Z $(toDF+":entry:entry:data_B")
90                KillDataFolder/Z $(toDF+":entry:entry:data_ML")
91                KillDataFolder/Z $(toDF+":entry:entry:data_MR")
92                KillDataFolder/Z $(toDF+":entry:entry:data_MT")
93                KillDataFolder/Z $(toDF+":entry:entry:data_MB")
94                KillDataFolder/Z $(toDF+":entry:entry:data_FL")
95                KillDataFolder/Z $(toDF+":entry:entry:data_FR")
96                KillDataFolder/Z $(toDF+":entry:entry:data_FT")
97                KillDataFolder/Z $(toDF+":entry:entry:data_FB")
98
99                return(0)
100        else
101                // need to do this the hard way, duplicate/O recursively
102                // see V_CopyToWorkFolder()
103               
104                // everything on the top level
105                V_DuplicateDataFolder($(toDF+":entry:entry"),fromStr,toStr,0,"",0)      //no recursion here
106                // control
107                V_DuplicateDataFolder($(toDF+":entry:entry:control"),fromStr,toStr,0,"",1)      //yes recursion here
108                // instrument
109                V_DuplicateDataFolder($(toDF+":entry:entry:instrument"),fromStr,toStr,0,"",1)   //yes recursion here
110                // reduction
111                V_DuplicateDataFolder($(toDF+":entry:entry:reduction"),fromStr,toStr,0,"",1)    //yes recursion here
112                // sample
113                V_DuplicateDataFolder($(toDF+":entry:entry:sample"),fromStr,toStr,0,"",1)       //yes recursion here
114
115        endif   
116       
117        return(0)
118end
119
120
121////////
122// see the help entry for IndexedDir for help on (possibly) how to do this faster
123// -- see the function Function ScanDirectories(pathName, printDirNames)
124//
125
126
127// from IgorExchange On July 17th, 2011 jtigor
128// started from "Recursively List Data Folder Contents"
129// Posted July 15th, 2011 by hrodstein
130//
131//
132//
133Proc V_CopyWorkFolderTest(dataFolderStr, fromStr, toStr, level, sNBName, recurse)
134        String dataFolderStr="root:Packages:NIST:VSANS:RAW"
135        String fromStr = "RAW"
136        String toStr="SAM"
137        Variable level=0
138        String sNBName="DataFolderTree"
139        Variable recurse = 1
140       
141        V_DuplicateDataFolder($dataFolderStr, fromStr, toStr, level, sNBName, recurse)
142
143
144end
145
146// ListDataFolder(dfr, level)
147// Recursively lists objects in data folder.
148// Pass data folder path for dfr and 0 for level.
149// pass level == 0 for the first call
150//  sNBName = "" prints nothing. any name will generate a notebook
151//
152// recurse == 0 will do only the specified folder, anything else will recurse all levels
153// toStr is the string name of the top-level folder only, not the full path
154//
155//
156Function V_DuplicateDataFolder(dfr, fromStr, toStr, level, sNBName,recurse)
157        DFREF dfr
158        String fromStr
159        String toStr
160        Variable level                  // Pass 0 to start
161        String sNBName
162        Variable recurse
163 
164        String name
165        String dfName
166        String sString
167       
168        String toDF = ""
169 
170        if (level == 0)         // this is the data folder, generate if needed in the destination
171                name = GetDataFolder(1, dfr)
172//              sPrintf sString, "%s (data folder)\r", name
173                toDF = ReplaceString(fromStr,name,toStr,1)              // case-sensitive replace
174                sprintf sString, "NewDataFolder/O %s\r",toDF
175                NewDataFolder/O $(RemoveEnding(toDF,":"))                       // remove trailing semicolon if it's there
176               
177                V_WriteBrowserInfo(sString, 1, sNBName)
178        endif
179 
180        dfName = GetDataFolder(1, dfr)
181        toDF = ReplaceString(fromStr,dfName,toStr,1)            // case-sensitive replace
182        Variable i
183 
184        String indentStr = "\t"
185        for(i=0; i<level; i+=1)
186                indentStr += "\t"
187        endfor
188 
189        Variable numWaves = CountObjectsDFR(dfr, 1)
190        for(i=0; i<numWaves; i+=1)
191                name = GetIndexedObjNameDFR(dfr, 1, i)
192                //
193                // wave type does not matter now. Duplicate does not care
194                //
195                sPrintf sString, "Duplicate/O  %s,  %s\r",dfName+name,toDF+name
196                Duplicate/O $(dfName+name),$(toDF+name)
197               
198                V_WriteBrowserInfo(sString, 2, sNBName)
199        endfor 
200 
201        Variable numNumericVariables = CountObjectsDFR(dfr, 2) 
202        for(i=0; i<numNumericVariables; i+=1)
203                name = GetIndexedObjNameDFR(dfr, 2, i)
204                sPrintf sString, "%s%s (numeric variable)\r", indentStr, name
205                V_WriteBrowserInfo(sString, 3, sNBName)
206        endfor 
207 
208        Variable numStringVariables = CountObjectsDFR(dfr, 3)   
209        for(i=0; i<numStringVariables; i+=1)
210                name = GetIndexedObjNameDFR(dfr, 3, i)
211                sPrintf sString, "%s%s (string variable)\r", indentStr, name
212                V_WriteBrowserInfo(sString, 4, sNBName)
213        endfor 
214
215        if(recurse)
216                Variable numDataFolders = CountObjectsDFR(dfr, 4)       
217                for(i=0; i<numDataFolders; i+=1)
218                        name = GetIndexedObjNameDFR(dfr, 4, i)
219//                      sPrintf sString, "%s%s (data folder)\r", indentStr, name
220                         dfName = GetDataFolder(1, dfr)
221                         
222                        toDF = ReplaceString(fromStr,dfName,toStr,1)            // case-sensitive replace
223                        sprintf sString, "NewDataFolder/O %s\r",toDF+name
224                        NewDataFolder/O $(toDF+name)
225                       
226                       
227                        V_WriteBrowserInfo(sString, 1, sNBName)
228                        DFREF childDFR = dfr:$(name)
229                        V_DuplicateDataFolder(childDFR, fromStr, toStr, level+1, sNBName, recurse)
230                endfor 
231        endif
232         
233//when finished walking tree, save as RTF with dialog   
234//      if(level == 0 && strlen(sNBName) != 0)
235//              SaveNotebook /I /S=4  $sNBName
236//      endif
237End
238 
239Function V_WriteBrowserInfo(sString, vType, sNBName)
240        String sString
241        Variable vType
242        String sNBName
243 
244        if(strlen(sNBName) == 0)
245//              print sString
246                return 0
247        endif
248        DoWindow $sNBName
249        if(V_flag != 1)
250                NewNoteBook/F=0 /N=$sNBName /V=1 as sNBName
251        else
252                DoWindow/F $sNBName
253        endif
254        Notebook $sNBName selection={endOfFile, endOfFile}
255        if(vType == 1)          // a data folder
256//              Notebook $sNBName fstyle=1
257                Notebook $sNBName text=sString
258//              Notebook $sNBName fstyle=-1
259        else
260                Notebook $sNBName text=sString 
261        endif
262 
263End
264
265///////////////////////////////
266
267
268// given the folder, duplicate the data -> linear_data and generate the error
269Function V_MakeDataError(folderStr)
270        String folderStr
271       
272        SetDataFolder $folderStr
273        Wave data=data
274        Duplicate/O data linear_data                    // at this point, the data is still the raw data, and is linear_data
275       
276        // proper error for counting statistics, good for low count values too
277        // rather than just sqrt(n)
278        // see N. Gehrels, Astrophys. J., 303 (1986) 336-346, equation (7)
279        // for S = 1 in eq (7), this corresponds to one sigma error bars
280        Duplicate/O linear_data linear_data_error
281        linear_data_error = 1 + sqrt(linear_data + 0.75)                               
282        //
283       
284        SetDataFolder root:
285        return(0)
286End
287
288
289
290
291
292/////////////////////
293
294
295
296
297//
298//Entry procedure from main panel
299//
300Proc AddFolder(oldType,newType)
301        String oldType,newType
302        Prompt oldType,"Source WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
303        Prompt newType,"Destination WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
304
305        // data folder "RAW" will be copied to "new" (either kills/copies or will overwrite)
306        Variable        err = Raw_to_work(newType)
307//      CopyHDFToWorkFolder(oldtype,newtype)
308End
309
310
311
312//testing procedure
313Proc Add_to_Workfile(newtype, doadd)
314        String newtype,doadd
315        Prompt newtype,"WORK data type",popup,"SAM;EMP;BGD;ADJ;"
316        Prompt doadd,"Add to current WORK contents?",popup,"No;Yes;"
317       
318        //macro will take whatever is in RAW folder and "ADD" it to the folder specified
319        //in the popup menu
320       
321        //"add" = yes/no, don't add to previous runs
322        //switch here - two separate functions to avoid (my) confusion
323        Variable err// = Raw_to_work(newtype)
324        if(cmpstr(doadd,"No")==0)
325                //don't add to prev work contents, copy RAW contents to work and convert
326                err = Raw_to_work(newtype)
327        else
328                //yes, add RAW to the current work folder contents
329                err = Add_raw_to_work(newtype)
330        endif
331       
332        String newTitle = "WORK_"+newtype
333        DoWindow/F VSANS_Data
334        DoWindow/T VSANS_Data, newTitle
335        KillStrings/Z newTitle
336       
337        //need to update the display with "data" from the correct dataFolder
338        UpdateDisplayInformation(newtype)
339       
340End
341
342
343//
344//will copy the current contents of the RAW folder to the newType work folder
345//and do the geometric corrections and normalization to monitor counts
346//(the function Add_Raw_to_work(type) adds multiple runs together)
347//
348//the current display type is updated to newType (global)
349//
350Function Raw_to_work(newType)
351        String newType
352       
353        Variable deadTime,defmon,total_mon,total_det,total_trn,total_numruns,total_rtime
354        Variable ii,jj,itim,cntrate,dscale,scale,uscale
355        String destPath
356       
357        String fname = newType
358        String detStr
359        Variable ctTime
360
361        //initialize values before normalization
362        total_mon=0
363        total_det=0
364        total_trn=0
365        total_numruns=0
366        total_rtime=0
367       
368        //Not adding multiple runs, so wipe out the old contents of the work folder and
369        // replace with the contents of raw
370
371        destPath = "root:Packages:NIST:VSANS:" + newType
372       
373        //copy from current dir (RAW) to work, defined by newType
374        CopyHDFToWorkFolder("RAW",newType)
375       
376        // now work with the waves from the destination folder.
377        Variable/G $(destPath + ":gIsLogscale")=0                       //overwite flag in newType folder, data converted (above) to linear scale
378//      String/G $(destPath + ":fileList") = textread[0]                        //a list of names of the files in the work file (1)             //02JUL13
379       
380        // apply corrections ---
381        // switches to control what is done, don't do the transmission correction for the BGD measurement
382        // start with the DIV correction, before conversion to mm
383        // then do all of the other corrections, order doesn't matter.
384        // rescaling to default monitor counts however, must be LAST.
385
386// each correction must loop over each detector. tedious.
387       
388        // (1) DIV correction
389        // do this in terms of pixels.
390        // TODO : This must also exist at the time the first work folder is generated.
391        //   So it must be in the user folder at the start of the experiment, and defined.
392        NVAR gDoDIVCor = root:Packages:NIST:VSANS:Globals:gDoDIVCor
393        if (gDoDIVCor == 1)
394                // need extra check here for file existence
395                // if not in DIV folder, load.
396                // if unable to load, skip correction and report error (Alert?)
397                for(ii=0;ii<8;ii+=1)
398                        detStr = StringFromList(ii, ksDetectorListNoB, ";")
399                        Wave w = V_getDetectorDataW(fname,detStr)
400                        Wave w_err = V_getDetectorDataErrW(fname,detStr)
401                        Wave w_dt = V_getDetector_deadtime(fname,detStr)
402                        Print "Doing DIV correction for "+ detStr
403//                      DIVCorrection(fill this in)
404                       
405                endfor
406        else
407                Print "DIV correction not done"         // not an error since correction was unchecked
408        endif
409       
410        // (2) non-linear correction   
411        NVAR gDoNonLinearCor = root:Packages:NIST:VSANS:Globals:gDoNonLinearCor
412        // generate a distance matrix for each of the detectors
413        if (gDoNonLinearCor == 1)
414                for(ii=0;ii<8;ii+=1)
415                        detStr = StringFromList(ii, ksDetectorListNoB, ";")
416                        Wave w = V_getDetectorDataW(fname,detStr)
417                        Wave w_err = V_getDetectorDataErrW(fname,detStr)
418                        Wave w_dt = V_getDetector_deadtime(fname,detStr)
419                        Print "Doing Non-linear correction for "+ detStr
420//                      NonLinearCorrection(fill this in)
421                       
422                endfor
423        else
424                Print "Non-linear correction not done"
425        endif
426       
427        // (3) solid angle correction
428        NVAR gDoSolidAngleCor = root:Packages:NIST:VSANS:Globals:gDoSolidAngleCor
429        if (gDoSolidAngleCor == 1)
430                for(ii=0;ii<8;ii+=1)
431                        detStr = StringFromList(ii, ksDetectorListNoB, ";")
432                        Wave w = V_getDetectorDataW(fname,detStr)
433                        Wave w_err = V_getDetectorDataErrW(fname,detStr)
434                        Wave w_dt = V_getDetector_deadtime(fname,detStr)
435                        Print "Doing Solid Angle correction for "+ detStr
436//                      SolidAngleCorrection(fill this in)
437                       
438                endfor
439        else
440                Print "Solid Angle correction not done"
441        endif   
442       
443        // (4) dead time correction
444        // TODO: -- remove the hard-wired test
445        // -- test for correct operation
446        // -- loop over all of the detectors
447        // -- B detector is a special case
448        NVAR gDoDeadTimeCor = root:Packages:NIST:VSANS:Globals:gDoDeadTimeCor
449        ctTime = V_getCount_time(fname)
450        if (gDoDeadTimeCor == 1)
451                for(ii=0;ii<8;ii+=1)
452                        detStr = StringFromList(ii, ksDetectorListNoB, ";")
453                        Wave w = V_getDetectorDataW(fname,detStr)
454                        Wave w_err = V_getDetectorDataErrW(fname,detStr)
455                        Wave w_dt = V_getDetector_deadtime(fname,detStr)
456                        Print "Doing DeadTime correction for "+ detStr
457//                      DeadTimeCorrectionTubes(w,w_err,w_dt,ctTime)
458                                //deadtime corrections
459//      itim = integersread[2]
460//      cntrate = sum(data,-inf,inf)/itim               //use sum of detector counts rather than scaler value
461//      //TODO - do correct dead time correction for tubes
462//      deadtime = 1//DetectorDeadtime(textread[3],textread[9],dateAndTimeStr=textRead[1],dtime=realsRead[48])  //pick the correct deadtime
463//      dscale = 1/(1-deadTime*cntrate)
464//     
465       
466// dead time correction
467//      data *= dscale          //deadtime correction for everyone else, including NCNR
468//      data_err *= dscale
469
470                endfor
471        else
472                Print "Dead Time correction not done"
473        endif   
474       
475        // (5) angle-dependent tube shadowing
476        NVAR gDoTubeShadowCor = root:Packages:NIST:VSANS:Globals:gDoTubeShadowCor
477        if (gDoTubeShadowCor == 1)
478       
479        else
480                Print "Tube shadowing correction not done"
481        endif   
482               
483        // (6) angle dependent transmission correction
484        NVAR gDoTrans = root:Packages:NIST:VSANS:Globals:gDoTransmissionCor
485        if (gDoTrans == 1)
486                for(ii=0;ii<8;ii+=1)
487                        detStr = StringFromList(ii, ksDetectorListNoB, ";")
488                        Wave w = V_getDetectorDataW(fname,detStr)
489                        Wave w_err = V_getDetectorDataErrW(fname,detStr)
490                        Wave w_dt = V_getDetector_deadtime(fname,detStr)
491                        Print "Doing Large-angle transmission correction for "+ detStr
492//                      TransmissionCorrection(fill this in)
493                       
494                endfor
495        else
496                Print "Sample Transmission correction not done"
497        endif   
498       
499        // (7) normalize to default monitor counts
500        // TODO -- each detector is rescaled separately, but the rescaling factor is global (only one monitor!)
501        // TODO -- but there are TWO monitors - so how to switch?
502        // TODO -- what do I really need to save?
503        defmon=1e8                      //default monitor counts
504        for(ii=0;ii<8;ii+=1)
505                detStr = StringFromList(ii, ksDetectorListNoB, ";")
506                Wave w = V_getDetectorDataW(fname,detStr)
507                Wave w_err = V_getDetectorDataErrW(fname,detStr)
508                Variable monCt = V_getBeamMonNormData(fname)
509                Print "Doing monitor normalization for "+ detStr
510//                      MonitorNormalization(fill this in)
511        //scale the data to the default montor counts
512                scale = defmon/monCt
513                w *= scale
514                w_err *= scale          //assumes total monitor count is so large there is essentially no error
515               
516                // V_getBeamMonNormSaved_count()
517                // save the true monitor counts? save the scaling factor?
518                String path = "entry:instrument:beam_monitor_norm:saved_count"
519                Wave/Z savW = $("root:Packages:NIST:VSANS:"+fname+":entry:"+path)
520                savW[0] = scale
521        endfor
522       
523       
524        // (not done) angle dependent efficiency correction
525        NVAR doEfficiency = root:Packages:NIST:VSANS:Globals:gDoDetectorEffCor
526
527       
528// this function, in the past did the non-linear, solid angle, transmission, and efficiency corrections all at once
529//      DetCorr(data,data_err,realsread,doEfficiency,doTrans)           //the parameters are waves, and will be changed by the function
530
531
532       
533        //update totals to put in the work header (at the end of the function)
534//      total_mon += realsread[0]
535//
536//      total_det += dscale*realsread[2]
537//
538//      total_trn += realsread[39]
539//      total_rtime += integersread[2]
540//      total_numruns +=1
541//     
542
543        //all is done, except for the bookkeeping, updating the header information in the work folder
544
545//      integersread[3] = total_numruns                                         //numruns = 1
546//      realsread[1] = total_mon                        //save the true monitor count
547//      realsread[0] = defmon                                   //monitor ct = defmon
548//      realsread[2] = scale*total_det                  //scaled detector counts
549//     
550        //reset the current displaytype to "newtype"
551        String/G root:myGlobals:gDataDisplayType=newType
552       
553        //return to root folder (redundant)
554        SetDataFolder root:
555       
556        Return(0)
557End
558
559
560//will "ADD" the current contents of the RAW folder to the newType work folder
561//and will ADD the RAW contents to the existing content of the newType folder
562// - used when adding multiple runs together
563//(the function Raw_to_work(type) makes a fresh workfile)
564//
565//the current display type is updated to newType (global)
566Function Add_raw_to_work(newType)
567        String newType
568       
569        // NEW OCT 2014
570        // this corrects for adding raw data files with different attenuation   
571        // does nothing if the attenuation of RAW and destination are the same
572        NVAR doAdjustRAW_Atten = root:Packages:NIST:gDoAdjustRAW_Atten
573        if(doAdjustRAW_Atten)
574                Adjust_RAW_Attenuation(newType)
575        endif
576       
577        String destPath=""
578       
579        // if the desired workfile doesn't exist, let the user know, and just make a new one
580        if(WaveExists($("root:Packages:NIST:"+newType + ":data")) == 0)
581                Print "There is no old work file to add to - a new one will be created"
582                //call Raw_to_work(), then return from this function
583                Raw_to_Work(newType)
584                Return(0)               //does not generate an error - a single file was converted to work.newtype
585        Endif
586       
587        NVAR pixelsX = root:myGlobals:gNPixelsX
588        NVAR pixelsY = root:myGlobals:gNPixelsY
589       
590        //now make references to data in newType folder
591        DestPath="root:Packages:NIST:"+newType 
592        WAVE data=$(destPath +":linear_data")                   // these wave references point to the EXISTING work data
593        WAVE data_copy=$(destPath +":data")                     // these wave references point to the EXISTING work data
594        WAVE dest_data_err=$(destPath +":linear_data_error")                    // these wave references point to the EXISTING work data
595        WAVE/T textread=$(destPath + ":textread")
596        WAVE integersread=$(destPath + ":integersread")
597        WAVE realsread=$(destPath + ":realsread")
598       
599        Variable deadTime,defmon,total_mon,total_det,total_trn,total_numruns,total_rtime
600        Variable ii,jj,itim,cntrate,dscale,scale,uscale,wrk_beamx,wrk_beamy,xshift,yshift
601
602
603        defmon=1e8                      //default monitor counts
604       
605        //Yes, add to previous run(s) in work, that does exist
606        //use the actual monitor count run.savmon rather than the normalized monitor count
607        //in run.moncnt and unscale the work data
608       
609        total_mon = realsread[1]        //saved monitor count
610        uscale = total_mon/defmon               //unscaling factor
611        total_det = uscale*realsread[2]         //unscaled detector count
612        total_trn = uscale*realsread[39]        //unscaled trans det count
613        total_numruns = integersread[3] //number of runs in workfile
614        total_rtime = integersread[2]           //total counting time in workfile
615        //retrieve workfile beamcenter
616        wrk_beamx = realsread[16]
617        wrk_beamy = realsread[17]
618        //unscale the workfile data in "newType"
619        //
620        //check for log-scaling and adjust if necessary
621        // should not be needed now - using display flag instead
622//      ConvertFolderToLinearScale(newType)
623        //
624        //then unscale the data array
625        data *= uscale
626        dest_data_err *= uscale
627       
628        //DetCorr() has not been applied to the data in RAW , do it now in a local reference to the raw data
629        WAVE raw_data = $"root:Packages:NIST:RAW:linear_data"
630        WAVE raw_data_err = $"root:Packages:NIST:RAW:linear_data_error"
631        WAVE raw_reals =  $"root:Packages:NIST:RAW:realsread"
632        WAVE/T raw_text = $"root:Packages:NIST:RAW:textread"
633        WAVE raw_ints = $"root:Packages:NIST:RAW:integersread"
634       
635        //check for log-scaling of the raw data - make sure it's linear
636        // should not be needed now - using display flag instead
637//      ConvertFolderToLinearScale("RAW")
638       
639        // switches to control what is done, don't do the transmission correction for the BGD measurement
640        NVAR doEfficiency = root:Packages:NIST:gDoDetectorEffCorr
641        NVAR gDoTrans = root:Packages:NIST:gDoTransmissionCorr
642        Variable doTrans = gDoTrans
643        if(cmpstr("BGD",newtype) == 0)
644                doTrans = 0             //skip the trans correction for the BGD file but don't change the value of the global
645        endif   
646       
647        DetCorr(raw_data,raw_data_err,raw_reals,doEfficiency,doTrans)   //applies correction to raw_data, and overwrites it
648       
649        //deadtime corrections to raw data
650        // TODO - do the tube correction for dead time now
651        deadTime = 1//DetectorDeadtime(raw_text[3],raw_text[9],dateAndTimeStr=raw_text[1],dtime=raw_reals[48])          //pick the correct detector deadtime, switch on date too
652        itim = raw_ints[2]
653        cntrate = sum(raw_data,-inf,inf)/itim           //080802 use data sum, rather than scaler value
654        dscale = 1/(1-deadTime*cntrate)
655
656#if (exists("ILL_D22")==6)
657        Variable tubeSum
658        // for D22 detector might need to use cntrate/128 as it is the tube response
659        for(ii=0;ii<pixelsX;ii+=1)
660                //sum the counts in each tube
661                tubeSum = 0
662                for(jj=0;jj<pixelsY;jj+=1)
663                        tubeSum += data[jj][ii]
664                endfor
665                // countrate in tube ii
666                cntrate = tubeSum/itim
667                // deadtime scaling in tube ii
668                dscale = 1/(1-deadTime*cntrate)
669                // multiply data[ii][] by the dead time
670                raw_data[][ii] *= dscale
671                raw_data_err[][ii] *= dscale
672        endfor
673#else
674        // dead time correction on all other RAW data, including NCNR
675        raw_data *= dscale
676        raw_data_err *= dscale
677#endif
678
679        //update totals by adding RAW values to the local ones (write to work header at end of function)
680        total_mon += raw_reals[0]
681
682        total_det += dscale*raw_reals[2]
683
684        total_trn += raw_reals[39]
685        total_rtime += raw_ints[2]
686        total_numruns +=1
687       
688        //do the beamcenter shifting if there is a mismatch
689        //and then add the two data sets together, changing "data" since it is the workfile data
690        xshift = raw_reals[16] - wrk_beamx
691        yshift = raw_reals[17] - wrk_beamy
692       
693        If((xshift != 0) || (yshift != 0))
694                DoAlert 1,"Do you want to ignore the beam center mismatch?"
695                if(V_flag==1)
696                        xshift=0
697                        yshift=0
698                endif
699        endif
700       
701        If((xshift == 0) && (yshift == 0))              //no shift, just add them
702                data += raw_data                //deadtime correction has already been done to the raw data
703                dest_data_err = sqrt(dest_data_err^2 + raw_data_err^2)                  // error of the sum
704        Endif
705       
706        //scale the data to the default montor counts
707        scale = defmon/total_mon
708        data *= scale
709        dest_data_err *= scale
710       
711        // keep "data" and linear_data in sync in the destination folder
712        data_copy = data
713       
714        //all is done, except for the bookkeeping of updating the header info in the work folder
715        textread[1] = date() + " " + time()             //date + time stamp
716        integersread[3] = total_numruns                                         //numruns = more than one
717        realsread[1] = total_mon                        //save the true monitor count
718        realsread[0] = defmon                                   //monitor ct = defmon
719        integersread[2] = total_rtime                   // total counting time
720        realsread[2] = scale*total_det                  //scaled detector counts
721        realsread[39] = scale*total_trn                 //scaled transmission counts
722       
723        //Add the added raw filename to the list of files in the workfile
724        String newfile = ";" + raw_text[0]
725        SVAR oldList = $(destPath + ":fileList")
726        String/G $(destPath + ":fileList") = oldList + newfile
727       
728        //reset the current displaytype to "newtype"
729        String/G root:myGlobals:gDataDisplayType=newType
730       
731        //return to root folder (redundant)
732        SetDataFolder root:
733       
734        Return(0)
735End
736
737
738//used for adding DRK (beam shutter CLOSED) data to a workfile
739//force the monitor count to 1, since it's irrelevant
740// run data through normal "add" step, then unscale default monitor counts
741//to get the data back on a simple time basis
742//
743Function Raw_to_Work_NoNorm(type)
744        String type
745       
746        WAVE reals=$("root:Packages:NIST:RAW:realsread")
747        reals[1]=1              //true monitor counts, still in raw
748        Raw_to_work(type)
749        //data is now in "type" folder
750        WAVE data=$("root:Packages:NIST:"+type+":linear_data")
751        WAVE data_copy=$("root:Packages:NIST:"+type+":data")
752        WAVE data_err=$("root:Packages:NIST:"+type+":linear_data_error")
753        WAVE new_reals=$("root:Packages:NIST:"+type+":realsread")
754       
755        Variable norm_mon,tot_mon,scale
756       
757        norm_mon = new_reals[0]         //should be 1e8
758        tot_mon = new_reals[1]          //should be 1
759        scale= norm_mon/tot_mon
760       
761        data /= scale           //unscale the data
762        data_err /= scale
763       
764        // to keep "data" and linear_data in sync
765        data_copy = data
766       
767        return(0)
768End
769
770//used for adding DRK (beam shutter CLOSED) data to a workfile
771//force the monitor count to 1, since it's irrelevant
772// run data through normal "add" step, then unscale default monitor counts
773//to get the data back on a simple time basis
774//
775Function Add_Raw_to_Work_NoNorm(type)
776        String type
777       
778        WAVE reals=$("root:Packages:NIST:RAW:realsread")
779        reals[1]=1              //true monitor counts, still in raw
780        Add_Raw_to_work(type)
781        //data is now in "type" folder
782        WAVE data=$("root:Packages:NIST:"+type+":linear_data")
783        WAVE data_copy=$("root:Packages:NIST:"+type+":data")
784        WAVE data_err=$("root:Packages:NIST:"+type+":linear_data_error")
785        WAVE new_reals=$("root:Packages:NIST:"+type+":realsread")
786       
787        Variable norm_mon,tot_mon,scale
788       
789        norm_mon = new_reals[0]         //should be 1e8
790        tot_mon = new_reals[1]          //should be equal to the number of runs (1 count per run)
791        scale= norm_mon/tot_mon
792       
793        data /= scale           //unscale the data
794        data_err /= scale
795       
796        // to keep "data" and linear_data in sync
797        data_copy = data
798       
799        return(0)
800End
801
Note: See TracBrowser for help on using the repository browser.