Ignore:
Timestamp:
Nov 3, 2014 11:15:23 AM (8 years ago)
Author:
srkline
Message:

Marquee.ipf -- added procedures (to the end of the file) that are extensions of the "BoxSum?" functionality. Instead of a rectangular box, these will sum over a series of files, using a defined region that is a q-annulus (+/-), or sectors, or arcs. This is expected to be useful for event mode data.

Location:
sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/Marquee.ipf

    r947 r949  
    22#pragma version=5.0 
    33#pragma IgorVersion=6.1 
     4 
     5/// NOV 2014 SRK ----- 
     6// 
     7//  added procedures (to the end of this file) that are extensions of the "BoxSum" functionality 
     8// -- instead of a rectangular box, these will sum over a series of files, using a defined region that  
     9// is a q-annulus (+/-), or sectors, or arcs. This is expected to be useful for event mode data 
     10// 
     11// 
     12// 
     13// 
     14 
    415 
    516//////////// 
     
    811822        return 0 
    812823End 
     824 
     825 
     826////////////////// 
     827// 
     828// -- Extensions of "Box Sum" 
     829// 
     830// some of these are duplicated procedures - these could be more smartly written as a single set of fucntions 
     831// since the annulus sum is a sepcial case of the arc sum - but I'm just trying to get this to work 
     832// first, then figure out if it's really worth figuring out a new way to present this to users 
     833// either though the average panel, or through the event mode panel 
     834// 
     835// right now, these items are presented through the (awkward) marquee menu, as the box sum was. 
     836// these would be much better served with a panel presentation - like the average panel where these 
     837// input values are already (almost) collected. 
     838// 
     839// -- some tricks: 
     840//   when the last file is done processing, toggle from log/lin scale. The region that was summed has been set 
     841// to NaN, so it will be visible after toggling the display. 
     842// -- if there is a binTimes wave, be sure to grab that and save it elsewhere, or it will be lost, and all you'll 
     843//   have is cts vs. run number. 
     844// 
     845// 
     846// -- what's missing? 
     847//  -- automatically picking up the time wave. currently only the file ID is collected, since that's 
     848//      the run number list. But the clock time is a function of binning, if event mode is used. this 
     849//      can be copied directly from the bin results (wave = BinEndTime, skipping the first 0 time point). 
     850//      But it's a manual step. If any run numbers are skipped, it's a mess. 
     851//  -- if added to the average panel, the "arc" option isn't there, and someone will surely ask for it 
     852//  -- a quick way of displaying what was actually used in the sum -- the NaN trick is good, but it 
     853//      requires recompiling. Can I set a flag somewhere? 
     854// 
     855// 
     856// 
     857// Oct 2014 SRK 
     858// 
     859 
     860 
     861// 
     862// promts the user for a range of file numbers to perform the sum over 
     863// list must be comma delimited numbers (or dashes) just as in the BuildProtocol panel 
     864// q-Center and delta-Q is entered by the user 
     865// 
     866Function AnnulusSum() :  GraphMarquee 
     867        GetMarquee left,bottom 
     868        if(V_flag == 0) 
     869                Abort "There is no Marquee" 
     870        Endif 
     871        SVAR dispType=root:myGlobals:gDataDisplayType 
     872        if(cmpstr(dispType,"RealTime")==0) 
     873                Print "Can't do an AnnulusSum for a RealTime file" 
     874                return(1) 
     875        endif 
     876         
     877        String fileStr="",msgStr="Enter a comma-delimited list of run numbers, use dashes for ranges" 
     878        String type="RAW" 
     879        Variable qCenter,deltaQ 
     880        Prompt fileStr,msgStr 
     881        Prompt qCenter, "Enter the q-center (A)" 
     882        Prompt deltaQ, "Enter the delta Q +/- (A)" 
     883        Prompt type,"RAW or Normalized (SAM)",popup,"RAW;SAM;" 
     884        DoPrompt "Pick the file range",fileStr,type,qCenter,deltaQ 
     885        Print "fileStr = ",fileStr 
     886        printf "QCenter +/- deltaQ = %g +/- %g\r",qCenter,deltaQ 
     887         
     888        DoAnnulusSum(fileStr,qCenter,deltaQ,type) 
     889         
     890        return(0) 
     891End      
     892                                 
     893//does a sum over each of the files in the list over the specified range 
     894// x,y are assumed to already be in-bounds of the data array 
     895// output is to AnnulusCounts waves 
     896// 
     897Function DoAnnulusSum(fileStr,qCtr,delta,type) 
     898        String fileStr 
     899        Variable qCtr,delta 
     900        String type 
     901         
     902        //parse the list of file numbers 
     903        String fileList="",item="",pathStr="",fullPath="" 
     904        Variable ii,num,err,cts,ct_err 
     905         
     906        PathInfo catPathName 
     907        If(V_Flag==0) 
     908                Abort "no path selected" 
     909        Endif 
     910        pathStr = S_Path 
     911         
     912        fileList=ParseRunNumberList(fileStr) 
     913        num=ItemsInList(fileList,",") 
     914         
     915        //loop over the list 
     916        //add each file to SAM (to normalize to monitor counts) 
     917        //sum over the annulus 
     918        //print the results 
     919        Make/O/N=(num) FileID,AnnulusCounts,AnnulusCount_err 
     920        Print "Results are stored in root:FileID and root:AnnulusCounts waves" 
     921        for(ii=0;ii<num;ii+=1) 
     922                item=StringFromList(ii,fileList,",") 
     923                FileID[ii] = GetRunNumFromFile(item)            //do this here, since the list is now valid 
     924                fullPath = pathStr+item 
     925                ReadHeaderAndData(fullPath) 
     926//              String/G root:myGlobals:gDataDisplayType="RAW" 
     927//              fRawWindowHook() 
     928                if(cmpstr(type,"SAM")==0) 
     929                        err = Raw_to_work("SAM") 
     930                endif 
     931                String/G root:myGlobals:gDataDisplayType=type 
     932                fRawWindowHook() 
     933                cts=SumCountsInAnnulus(qCtr,delta,ct_err,type) 
     934                AnnulusCounts[ii]=cts 
     935                AnnulusCount_err[ii]=ct_err 
     936                Print item+" counts = ",cts 
     937        endfor 
     938         
     939        DoAnnulusGraph(FileID,AnnulusCounts,AnnulusCount_err) 
     940         
     941        return(0) 
     942End 
     943 
     944 
     945//sums the data counts in the annulus specified by qCtr and delta (units of Q, not pixels) 
     946// 
     947Function SumCountsInAnnulus(qCtr,delta,ct_err,type) 
     948        Variable qCtr,delta,&ct_err 
     949        String type 
     950         
     951        Variable counts = 0,ii,jj,err2_sum,testQ 
     952         
     953        String dest =  "root:Packages:NIST:"+type 
     954         
     955        //check for logscale data, but don't change the data 
     956        NVAR gIsLogScale = $(dest + ":gIsLogScale") 
     957        if (gIsLogScale) 
     958                wave w=$(dest + ":linear_data") 
     959        else 
     960                wave w=$(dest + ":data") 
     961        endif 
     962        wave data_err = $(dest + ":linear_data_error") 
     963        Wave reals = $(dest + ":realsRead") 
     964        Variable xctr=reals[16],yctr=reals[17],sdd=reals[18],lam=reals[26],pixSize=reals[13]/10 
     965 
     966        err2_sum = 0            // running total of the squared error 
     967         
     968        for(ii=0;ii<128;ii+=1) 
     969                for(jj=0;jj<128;jj+=1) 
     970                        //test each q-value, sum if within range of annulus 
     971                        testQ = CalcQval(ii+1,jj+1,xctr,yctr,sdd,lam,pixSize) 
     972                         
     973                        if(testQ > (qCtr - delta) && testQ < (qCtr + delta)) 
     974                                counts += w[ii][jj] 
     975                                 
     976                                w[ii][jj] = NaN         //for testing -- sets included pixels to NaN (in linear_data) 
     977                                 
     978                                err2_sum += data_err[ii][jj]*data_err[ii][jj] 
     979                        endif 
     980                endfor 
     981        endfor 
     982         
     983         
     984        err2_sum = sqrt(err2_sum) 
     985        ct_err = err2_sum 
     986         
     987//      Print "error = ",err2_sum 
     988//      Print "error/counts = ",err2_sum/counts 
     989         
     990         
     991        Return (counts) 
     992End 
     993 
     994 
     995 
     996Function DoAnnulusGraph(FileID,AnnulusCounts,AnnulusCount_err) 
     997        Wave FileID,AnnulusCounts,AnnulusCount_err 
     998         
     999        Sort FileID AnnulusCounts,FileID                //sort the waves, in case the run numbers were entered out of numerical order 
     1000         
     1001        DoWindow AnnulusCountsGraph 
     1002        if(V_flag == 0) 
     1003                Display /W=(5,44,383,306) AnnulusCounts vs FileID 
     1004                DoWindow/C AnnulusCountsGraph 
     1005                ModifyGraph mode=4 
     1006                ModifyGraph marker=8 
     1007                ModifyGraph grid=2 
     1008                ModifyGraph mirror=2 
     1009                ErrorBars/T=0 AnnulusCounts Y,wave=(AnnulusCount_err,AnnulusCount_err) 
     1010                Label left "Counts (per 10^8 monitor counts)" 
     1011                Label bottom "Run Number" 
     1012        endif    
     1013        return(0) 
     1014End 
     1015 
     1016 
     1017 
     1018///////////////////////// 
     1019// Duplicate of the procedures - this time for arcs, which are identical to the annulus, but not full circles. 
     1020// 
     1021 
     1022////////////////// 
     1023// 
     1024// promts the user for a range of file numbers to perform the sum over 
     1025// list must be comma delimited numbers (or dashes) just as in the BuildProtocol panel 
     1026// q-Center and delta-Q is entered by the user 
     1027// phi and delta phi are entered 
     1028// left, right, or both sides are selected too 
     1029// 
     1030// set deltaQ huge to get the full sector 
     1031// 
     1032Function ArcSum() :  GraphMarquee 
     1033 
     1034        SVAR dispType=root:myGlobals:gDataDisplayType 
     1035        if(cmpstr(dispType,"RealTime")==0) 
     1036                Print "Can't do an ArcSum for a RealTime file" 
     1037                return(1) 
     1038        endif 
     1039         
     1040        String fileStr="",msgStr="Enter a comma-delimited list of run numbers, use dashes for ranges" 
     1041        String type="RAW",sideStr="" 
     1042        Variable qCenter,deltaQ,phi,deltaPhi 
     1043        Prompt fileStr,msgStr 
     1044        Prompt qCenter, "Enter the q-center (A)" 
     1045        Prompt deltaQ, "Enter the delta Q +/- (A)" 
     1046        Prompt type,"RAW or Normalized (SAM)",popup,"RAW;SAM;" 
     1047        Prompt sideStr,"One, or both sides",popup,"both;one;" 
     1048        Prompt phi, "Enter the angle phi (0,360)" 
     1049        Prompt deltaPhi, "Enter the delta phi angle (degrees)" 
     1050 
     1051        DoPrompt "Pick the file range",fileStr,type,qCenter,deltaQ,sideStr,phi,deltaPhi 
     1052        Print "fileStr = ",fileStr 
     1053        printf "QCenter +/- deltaQ = %g +/- %g\r",qCenter,deltaQ 
     1054        Print "sideStr = ",sideStr 
     1055        printf "phi +/- deltaPhi = %g +/- %g\r",phi,deltaPhi 
     1056                 
     1057        DoArcSum(fileStr,qCenter,deltaQ,type,sideStr,phi,deltaPhi) 
     1058         
     1059        return(0) 
     1060End      
     1061                                 
     1062//does a sum over each of the files in the list over the specified range 
     1063// x,y are assumed to already be in-bounds of the data array 
     1064// output is to ArcCounts waves 
     1065// 
     1066Function DoArcSum(fileStr,qCtr,delta,type,sideStr,phi,deltaPhi) 
     1067        String fileStr 
     1068        Variable qCtr,delta 
     1069        String type,sideStr 
     1070        Variable phi,deltaPhi 
     1071         
     1072        //parse the list of file numbers 
     1073        String fileList="",item="",pathStr="",fullPath="" 
     1074        Variable ii,num,err,cts,ct_err 
     1075         
     1076        PathInfo catPathName 
     1077        If(V_Flag==0) 
     1078                Abort "no path selected" 
     1079        Endif 
     1080        pathStr = S_Path 
     1081         
     1082        fileList=ParseRunNumberList(fileStr) 
     1083        num=ItemsInList(fileList,",") 
     1084         
     1085        //loop over the list 
     1086        //add each file to SAM (to normalize to monitor counts) 
     1087        //sum over the annulus 
     1088        //print the results 
     1089        Make/O/N=(num) FileID,ArcCounts,ArcCount_err 
     1090        Print "Results are stored in root:FileID and root:AnnulusCounts waves" 
     1091        for(ii=0;ii<num;ii+=1) 
     1092                item=StringFromList(ii,fileList,",") 
     1093                FileID[ii] = GetRunNumFromFile(item)            //do this here, since the list is now valid 
     1094                fullPath = pathStr+item 
     1095                ReadHeaderAndData(fullPath) 
     1096//              String/G root:myGlobals:gDataDisplayType="RAW" 
     1097//              fRawWindowHook() 
     1098                if(cmpstr(type,"SAM")==0) 
     1099                        err = Raw_to_work("SAM") 
     1100                endif 
     1101                String/G root:myGlobals:gDataDisplayType=type 
     1102                fRawWindowHook() 
     1103                cts=SumCountsInArc(qCtr,delta,ct_err,type,sideStr,phi,deltaPhi) 
     1104                ArcCounts[ii]=cts 
     1105                ArcCount_err[ii]=ct_err 
     1106                Print item+" counts = ",cts 
     1107        endfor 
     1108         
     1109        DoArcGraph(FileID,ArcCounts,ArcCount_err) 
     1110         
     1111        return(0) 
     1112End 
     1113 
     1114 
     1115//sums the data counts in the annulus specified by qCtr and delta (units of Q, not pixels) 
     1116// 
     1117Function SumCountsInArc(qCtr,delta,ct_err,type,sideStr,phi,deltaPhi) 
     1118        Variable qCtr,delta,&ct_err 
     1119        String type,sideStr 
     1120        Variable phi,deltaPhi 
     1121         
     1122        Variable counts = 0,ii,jj,err2_sum,testQ,testPhi 
     1123         
     1124        String dest =  "root:Packages:NIST:"+type 
     1125         
     1126        //check for logscale data, but don't change the data 
     1127        NVAR gIsLogScale = $(dest + ":gIsLogScale") 
     1128        if (gIsLogScale) 
     1129                wave w=$(dest + ":linear_data") 
     1130        else 
     1131                wave w=$(dest + ":data") 
     1132        endif 
     1133        wave data_err = $(dest + ":linear_data_error") 
     1134        Wave reals = $(dest + ":realsRead") 
     1135        Variable xctr=reals[16],yctr=reals[17],sdd=reals[18],lam=reals[26],pixSize=reals[13]/10 
     1136 
     1137 
     1138        err2_sum = 0            // running total of the squared error 
     1139         
     1140        for(ii=0;ii<128;ii+=1) 
     1141                for(jj=0;jj<128;jj+=1) 
     1142                        //test each q-value, sum if within range of annulus 
     1143                        testQ = CalcQval(ii+1,jj+1,xctr,yctr,sdd,lam,pixSize)                    
     1144                        if(testQ > (qCtr - delta) && testQ < (qCtr + delta)) 
     1145                                //then test the arc 
     1146                                testPhi = FindPhi(ii+1-xCtr, jj+1-yctr)                 //does not need to be in cm, pixels is fine 
     1147                                testPhi = testPhi*360/2/pi              //convert to degrees 
     1148                                if(phiTestArcSum(testPhi,phi,deltaPhi,sideStr)) 
     1149                                                         
     1150                                                counts += w[ii][jj] 
     1151                                                 
     1152                                                w[ii][jj] = NaN         //for testing -- sets included pixels to NaN (in linear_data) 
     1153                                                 
     1154                                                err2_sum += data_err[ii][jj]*data_err[ii][jj]    
     1155                                endif 
     1156                        endif 
     1157                endfor 
     1158        endfor 
     1159         
     1160         
     1161        err2_sum = sqrt(err2_sum) 
     1162        ct_err = err2_sum 
     1163         
     1164//      Print "error = ",err2_sum 
     1165//      Print "error/counts = ",err2_sum/counts 
     1166         
     1167        Return (counts) 
     1168End 
     1169 
     1170// since the test for arcs is more complex, send it out... 
     1171// 
     1172// NOTE these definitions of angles are NOT the same as the average panel 
     1173// 
     1174// testPhi is in the range (0,360) 
     1175// phi is (0,360) 
     1176// side is either one or both (mirror it 180 degrees) 
     1177// 
     1178Function phiTestArcSum(testPhi,phi,dPhi,side) 
     1179        Variable testPhi,phi,dPhi 
     1180        String side 
     1181         
     1182        Variable pass = 0 
     1183        variable low,hi, range 
     1184         
     1185        if( (cmpstr(side,"one")==0) || (cmpstr(side,"both")==0) ) 
     1186                low = phi - dphi 
     1187                hi = phi + dphi          
     1188                if(testPhi > low && testPhi < hi) 
     1189                        return(1) 
     1190                         
     1191                else 
     1192         
     1193                        if(low < 0)     //get the gap between low+360 and 360 
     1194                                low += 360 
     1195                                if(testPhi > low && testPhi < 360) 
     1196                                        return(1) 
     1197                                endif 
     1198                        endif 
     1199                         
     1200                        if(hi > 360)            //get the gap between 0 and (hi-360) 
     1201                                hi -= 360 
     1202                                if(testPhi > 0 && testPhi < hi) 
     1203                                        return(1) 
     1204                                endif 
     1205                        endif 
     1206                         
     1207                endif            
     1208        Endif           //one side or both 
     1209         
     1210        if((cmpstr(side,"both")==0) )           //now catch the 180 deg mirror 
     1211 
     1212                if(phi + 180 > 360) 
     1213                        phi = phi - 180 
     1214                else 
     1215                        phi = phi + 180 
     1216                endif 
     1217 
     1218                low = phi - dphi 
     1219                hi = phi + dphi 
     1220 
     1221                if(testPhi > low && testPhi < hi) 
     1222                        return(1) 
     1223                else 
     1224                        if(low < 0)     //get the gap between low+360 and 360 
     1225                                low += 360 
     1226                                if(testPhi > low && testPhi < 360) 
     1227                                        return(1) 
     1228                                endif 
     1229                        endif 
     1230                         
     1231                        if(hi > 360)            //get the gap between 0 and (hi-360) 
     1232                                hi -= 360 
     1233                                if(testPhi > 0 && testPhi < hi) 
     1234                                        return(1) 
     1235                                endif 
     1236                        endif 
     1237         
     1238                endif 
     1239                         
     1240        Endif           //both 
     1241 
     1242         
     1243        return(pass) 
     1244end 
     1245 
     1246Function DoArcGraph(FileID,ArcCounts,ArcCount_err) 
     1247        Wave FileID,ArcCounts,ArcCount_err 
     1248         
     1249        Sort FileID ArcCounts,FileID            //sort the waves, in case the run numbers were entered out of numerical order 
     1250         
     1251        DoWindow ArcCountsGraph 
     1252        if(V_flag == 0) 
     1253                Display /W=(5,44,383,306) ArcCounts vs FileID 
     1254                DoWindow/C ArcCountsGraph 
     1255                ModifyGraph mode=4 
     1256                ModifyGraph marker=8 
     1257                ModifyGraph grid=2 
     1258                ModifyGraph mirror=2 
     1259                ErrorBars/T=0 ArcCounts Y,wave=(ArcCount_err,ArcCount_err) 
     1260                Label left "Counts (per 10^8 monitor counts)" 
     1261                Label bottom "Run Number" 
     1262        endif    
     1263        return(0) 
     1264End 
     1265 
     1266////////////////////////////// 
  • sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/Transmission.ipf

    r948 r949  
    494494        Make/O/D/N=0 $"root:myGlobals:TransHeaderInfo:S_Trans_Error" 
    495495        Make/O/D/N=0 $"root:myGlobals:TransHeaderInfo:S_Whole" 
     496         
     497        String/G root:myGlobals:TransHeaderInfo:gMatchingSampleFiles = "" 
     498 
    496499End 
    497500 
     
    18261829         
    18271830        Variable/G root:myGlobals:TransHeaderInfo:gNumMatchChars = numChars 
     1831        SVAR gMatchSamStr = root:myGlobals:TransHeaderInfo:gMatchingSampleFiles 
    18281832         
    18291833        Make/O/D/N=0 root:myGlobals:TransHeaderInfo:matchRows 
     
    18911895                case 1:          
    18921896                        // accept guess (assign, and calculate immediately) 
     1897                        gMatchSamStr="" 
    18931898                        num=numpnts(matchRows)          //this may have changed 
    18941899                        for(ii=0;ii<num;ii+=1) 
     
    18961901                                AssignSelTransFilesToData(matchRows[ii],matchRows[ii]) 
    18971902                                CalcSelTransFromHeader(matchRows[ii],matchRows[ii])             //does only that sample file 
     1903                                gMatchSamStr += samfile(matchRows[ii]) + ";" 
    18981904                        endfor                   
    18991905                        break                                            
     
    19051911                        break 
    19061912                case 0: // cancel 
     1913                        gMatchSamStr = "" 
    19071914                        // do nothing 
    19081915                        break 
Note: See TracChangeset for help on using the changeset viewer.