Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MaskBTP and CorrectLogTimes algorithms. Refs #8626
- Loading branch information
1 parent
bfc883e
commit f46c7b2
Showing
5 changed files
with
343 additions
and
0 deletions.
There are no files selected for viewing
69 changes: 69 additions & 0 deletions
69
Code/Mantid/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
""" | ||
Sometimes the clocks controlling different sample environments or other experimental log values are not synchronized. | ||
This algorithm attempts to make all (some) time series property logs start at the same time as the first time in the proton charge log. | ||
""" | ||
|
||
import mantid.simpleapi | ||
import mantid.api | ||
import mantid.kernel | ||
import numpy | ||
|
||
class CorrectLogTimes(mantid.api.PythonAlgorithm): | ||
""" Class to shift log times to match proton charge | ||
""" | ||
|
||
def category(self): | ||
""" Mantid required | ||
""" | ||
return "PythonAlgorithms;DataHandling\\Logs" | ||
|
||
def name(self): | ||
""" Mantid required | ||
""" | ||
return "CorrectLogTimes" | ||
|
||
|
||
def PyInit(self): | ||
self.declareProperty(mantid.api.WorkspaceProperty("Workspace", "",direction=mantid.kernel.Direction.InOut), "Input workspace") | ||
self.declareProperty("LogNames","",doc="Experimental og values to be shifted. If empty, will attempt to shift all logs") | ||
|
||
def PyExec(self): | ||
self.ws = self.getProperty("Workspace").value | ||
logNames = self.getProperty("LogNames").value | ||
|
||
logList=[] | ||
|
||
#check for parameters and build the result string | ||
for value in logNames.split(','): | ||
value=value.strip() | ||
if len(value)>0: | ||
if not self.ws.run().hasProperty(value): | ||
err = 'Property '+value+' not found' | ||
raise ValueError(err) | ||
else: | ||
logList.append(value) | ||
|
||
|
||
if len(logList)==0: | ||
logList=self.ws.getRun().keys() | ||
|
||
for x in logList: | ||
if x not in ['duration','proton_charge','start_time','run_title','run_start','run_number','gd_prtn_chrg','end_time']: | ||
try: | ||
self.ShiftTime(x) | ||
except: | ||
pass | ||
|
||
|
||
def ShiftTime(self, logName): | ||
""" | ||
shift the time in a given log to match the time in the proton charge log" | ||
""" | ||
PC = self.ws.getRun()['proton_charge'].firstTime() | ||
P = self.ws.getRun()[logName].firstTime() | ||
Tdiff = PC-P | ||
Tdiff_num = Tdiff.total_milliseconds()*1E-3 | ||
mantid.simpleapi.ChangeLogTime(InputWorkspace=self.ws, OutputWorkspace = self.ws, LogName = logName, TimeOffset = Tdiff_num) | ||
|
||
|
||
mantid.api.AlgorithmFactory.subscribe(CorrectLogTimes) |
171 changes: 171 additions & 0 deletions
171
Code/Mantid/Framework/PythonInterface/plugins/algorithms/MaskBTP.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
""" | ||
Algorithm to mask detectors in particular banks, tube, or pixels. It applies to the following instruments only: ARCS, CNCS, HYSPEC, SEQUOIA. | ||
If one of Bank, Tube, Pixel entries is left blank, it will apply to all elements of that type. For example: | ||
MaskBTP(w,Bank = "1") will completely mask all tubes and pixels in bank 1. | ||
MaskBTP(w,Pixel = "1,2") will mask all pixels 1 and 2, in all tubes, in all banks. | ||
The algorithm allows ranged inputs: Pixel = "1-8,121-128" is equivalent to Pixel = "1,2,3,4,5,6,7,8,121,122,123,124,125,126,127,128" | ||
Either the input workspace or the instrument must be set | ||
""" | ||
|
||
import mantid.simpleapi | ||
import mantid.api | ||
import mantid.kernel | ||
import numpy | ||
|
||
class MaskBTP(mantid.api.PythonAlgorithm): | ||
""" Class to generate grouping file | ||
""" | ||
|
||
def category(self): | ||
""" Mantid required | ||
""" | ||
return "PythonAlgorithms;Transforms\\Masking;Inelastic" | ||
|
||
def name(self): | ||
""" Mantid require | ||
""" | ||
return "MaskBTP" | ||
|
||
|
||
def PyInit(self): | ||
self.declareProperty(mantid.api.WorkspaceProperty("Workspace", "",direction=mantid.kernel.Direction.InOut, optional = mantid.api.PropertyMode.Optional), "Input workspace (optional)") | ||
allowedInstrumentList=mantid.kernel.StringListValidator(["","ARCS","CNCS","HYSPEC","SEQUOIA"]) | ||
self.declareProperty("Instrument","",validator=allowedInstrumentList,doc="One of the following instruments: ARCS, CNCS, HYSPEC, SEQUOIA") | ||
self.declareProperty("Bank","",doc="Bank(s) to be masked. If empty, will apply to all banks") | ||
self.declareProperty("Tube","",doc="Tube(s) to be masked. If empty, will apply to all tubes") | ||
self.declareProperty("Pixel","",doc="Pixel(s) to be masked. If empty, will apply to all pixels") | ||
self.declareProperty(mantid.kernel.IntArrayProperty(name="MaskedDetectors", direction=mantid.kernel.Direction.Output), doc="List of masked detectors") | ||
|
||
|
||
def PyExec(self): | ||
ws = self.getProperty("Workspace").value | ||
self.instrument=None | ||
self.instname = self.getProperty("Instrument").value | ||
bankString = self.getProperty("Bank").value | ||
tubeString = self.getProperty("Tube").value | ||
pixelString = self.getProperty("Pixel").value | ||
|
||
if self.instname == "" and ws == None: | ||
raise ValueError("No workspace or instrument were selected" ) | ||
|
||
if ws != None: | ||
self.instrument = ws.getInstrument() | ||
self.instname = self.instrument.getName() | ||
|
||
instrumentList=["ARCS","CNCS","HYSPEC","SEQUOIA"] | ||
try: | ||
instrumentList.index(self.instname) | ||
except: | ||
raise ValueError("Instrument "+self.instname+" not in the allowed list") | ||
|
||
if (self.instrument==None): | ||
IDF=mantid.api.ExperimentInfo.getInstrumentFilename(self.instname) | ||
ws=mantid.simpleapi.LoadEmptyInstrument(IDF,OutputWorkspace=self.instname+"MaskBTP") | ||
self.instrument=ws.getInstrument() | ||
|
||
if (bankString == ""): | ||
if (self.instname == "ARCS"): | ||
banks=numpy.arange(115)+1 | ||
elif (self.instname == "CNCS"): | ||
banks=numpy.arange(50)+1 | ||
elif (self.instname == "HYSPEC"): | ||
banks=numpy.arange(20)+1 | ||
elif (self.instname == "SEQUOIA"): | ||
banks=numpy.arange(113)+38 | ||
else: | ||
banks=self._parseBTPlist(bankString) | ||
|
||
if (tubeString == ""): | ||
tubes=numpy.arange(8)+1 | ||
else: | ||
tubes=self._parseBTPlist(tubeString) | ||
|
||
if(pixelString == ""): | ||
pixels=numpy.arange(128)+1 | ||
else: | ||
pixels=self._parseBTPlist(pixelString) | ||
|
||
|
||
|
||
detlist=[] | ||
for b in banks: | ||
ep=self._getEightPackHandle(b) | ||
for t in tubes: | ||
if ((t<1) or (t>8)): | ||
raise ValueError("Out of range index for tube number") | ||
else: | ||
for p in pixels: | ||
if ((p<1) or (p>128)): | ||
raise ValueError("Out of range index for pixel number") | ||
else: | ||
pid=ep[int(t-1)][int(p-1)].getID() | ||
detlist.append(pid) | ||
if len(detlist)> 0: | ||
mantid.simpleapi.MaskDetectors(Workspace=ws,DetectorList=detlist) | ||
else: | ||
self.log().information("no detectors within this range") | ||
self.setProperty("MaskedDetectors", numpy.array(detlist)) | ||
|
||
def _parseBTPlist(self,value): | ||
""" | ||
Helper function to transform a string into a list of integers | ||
For example "1,2-4,8-10" will become [1,2,3,4,8,9,10] | ||
It will deal with lists as well, so range(1,4) will still be [1,2,3] | ||
""" | ||
parsed = [] | ||
#split the commas | ||
parts = str(value).strip(']').strip('[').split(',') | ||
#now deal with the hyphens | ||
for p in parts: | ||
if len(p) > 0: | ||
elem = p.split("-") | ||
if len(elem) == 1: | ||
parsed.append(int(elem[0])) | ||
if len(elem) == 2: | ||
startelem = int(elem[0]) | ||
endelem = int(elem[1]) | ||
if endelem < startelem: | ||
raise ValueError("The element after the hyphen needs to be greater or equal than the first element") | ||
elemlist = range(startelem,endelem+1) | ||
parsed.extend(elemlist) | ||
return parsed | ||
|
||
def _getEightPackHandle(self,banknum): | ||
""" | ||
Helper function to return the handle to a given eightpack | ||
""" | ||
banknum=int(banknum) | ||
if self.instname=="ARCS": | ||
if (1<=banknum<= 38): | ||
return self.instrument[3][banknum-1][0] | ||
elif(39<=banknum<= 77): | ||
return self.instrument[4][banknum-39][0] | ||
elif(78<=banknum<=115): | ||
return self.instrument[5][banknum-78][0] | ||
else: | ||
raise ValueError("Out of range index for ARCS instrument bank numbers") | ||
elif self.instname=="CNCS": | ||
if (1<=banknum<= 50): | ||
return self.instrument[3][banknum-1][0] | ||
else: | ||
raise ValueError("Out of range index for CNCS instrument bank numbers") | ||
elif self.instname=="HYSPEC": | ||
if (1<=banknum<= 20): | ||
return self.instrument[3][banknum-1][0] | ||
else: | ||
raise ValueError("Out of range index for HYSPEC instrument bank numbers") | ||
elif self.instname=="SEQUOIA": | ||
if (38<=banknum<= 74): | ||
return self.instrument[3][banknum-38][0] | ||
elif(75<=banknum<= 113): | ||
return self.instrument[4][banknum-75][0] | ||
elif(114<=banknum<=150): | ||
return self.instrument[5][banknum-114][0] | ||
else: | ||
raise ValueError("Out of range index for SEQUOIA instrument bank numbers") | ||
|
||
mantid.api.AlgorithmFactory.subscribe(MaskBTP) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CorrectLogTimesTest.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import unittest | ||
from mantid.simpleapi import * | ||
from mantid.api import * | ||
from testhelpers import * | ||
from numpy import * | ||
|
||
class CorrectLogTimesTest(unittest.TestCase): | ||
|
||
def testCLTWrongLog(self): | ||
w=Load('CNCS_7860_event.nxs') | ||
|
||
try: | ||
CorrectLogTimes(Workspace=w,LogNames="s1") | ||
self.fail("Should not have got here. Should throw because wrong instrument.") | ||
except RuntimeError: | ||
pass | ||
finally: | ||
DeleteWorkspace(w) | ||
|
||
def testCLTsingle(self): | ||
w=Load('CNCS_7860_event.nxs') | ||
self.assertFalse(w.getRun()['proton_charge'].firstTime()==w.getRun()['Speed4'].firstTime()) | ||
CorrectLogTimes(Workspace=w,LogNames="Speed4") | ||
self.assertTrue(w.getRun()['proton_charge'].firstTime()==w.getRun()['Speed4'].firstTime()) | ||
self.assertFalse(w.getRun()['proton_charge'].firstTime()==w.getRun()['Speed5'].firstTime()) | ||
DeleteWorkspace(w) | ||
|
||
def testCLTall(self): | ||
w=Load('CNCS_7860_event.nxs') | ||
self.assertFalse(w.getRun()['proton_charge'].firstTime()==w.getRun()['Speed4'].firstTime()) | ||
CorrectLogTimes(Workspace=w,LogNames="") | ||
self.assertTrue(w.getRun()['proton_charge'].firstTime()==w.getRun()['Speed4'].firstTime()) | ||
self.assertTrue(w.getRun()['proton_charge'].firstTime()==w.getRun()['Speed5'].firstTime()) | ||
DeleteWorkspace(w) | ||
if __name__ == '__main__': | ||
unittest.main() |
65 changes: 65 additions & 0 deletions
65
Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MaskBTPTest.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import unittest | ||
from mantid.simpleapi import * | ||
from mantid.api import * | ||
from testhelpers import * | ||
from numpy import * | ||
|
||
class MaskBTPTest(unittest.TestCase): | ||
|
||
def testMaskBTPWrongInstrument(self): | ||
w=WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(30,5,False,False) | ||
AnalysisDataService.add('w',w) | ||
try: | ||
masklist = MaskBTP(Workspace=w,Pixel="1") | ||
self.fail("Should not have got here. Should throw because wrong instrument.") | ||
except RuntimeError: | ||
pass | ||
finally: | ||
DeleteWorkspace(w) | ||
|
||
def testMaskBTPWrongLimits(self): | ||
try: | ||
MaskBTP(Instrument='ARCS', Pixel="129") | ||
self.fail("Should not have got here.") | ||
except RuntimeError: | ||
pass | ||
try: | ||
MaskBTP(Instrument='SEQUOIA', Bank="1") | ||
self.fail("Should not have got here.") | ||
except RuntimeError: | ||
pass | ||
try: | ||
MaskBTP(Instrument='HYSPEC', Tube="18") | ||
self.fail("Should not have got here.") | ||
except RuntimeError: | ||
pass | ||
DeleteWorkspace("ARCSMaskBTP") | ||
DeleteWorkspace("HYSPECMaskBTP") | ||
DeleteWorkspace("SEQUOIAMaskBTP") | ||
|
||
def testMaskBTP(self): | ||
m1=MaskBTP(Instrument='CNCS', Pixel="1-3,5") | ||
m2=MaskBTP(Workspace='CNCSMaskBTP', Bank="1-2") | ||
m3=MaskBTP(Workspace='CNCSMaskBTP', Bank='5-7', Tube='3') | ||
p1=arange(400)*128 | ||
m1p=sort(concatenate((p1,p1+1,p1+2,p1+4))) | ||
self.assertTrue(array_equal(m1,m1p)) | ||
self.assertTrue(array_equal(m2,arange(2048))) | ||
b5t3=arange(128)+4*1024+2*128 | ||
self.assertTrue(array_equal(m3,concatenate((b5t3,b5t3+1024,b5t3+2048)))) | ||
#check whether some pixels are masked when they should | ||
w=mtd['CNCSMaskBTP'] | ||
self.assertTrue(w.getInstrument().getDetector(29696).isMasked()) #pixel1 | ||
self.assertTrue(w.getInstrument().getDetector(29697).isMasked()) #pixel2 | ||
self.assertTrue(w.getInstrument().getDetector(29698).isMasked()) #pixel3 | ||
self.assertTrue(not w.getInstrument().getDetector(29699).isMasked()) #pixel4 | ||
self.assertTrue(w.getInstrument().getDetector(29700).isMasked()) #pixel5 | ||
|
||
self.assertTrue(w.getInstrument().getDetector(1020).isMasked()) #bank 1 | ||
self.assertTrue(not w.getInstrument().getDetector(3068).isMasked()) #bank3, tube 8 | ||
|
||
self.assertTrue(w.getInstrument().getDetector(4400).isMasked()) #bank5, tube 3 | ||
DeleteWorkspace(w) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |