diff --git a/calibrationSuite/Stats.py b/calibrationSuite/Stats.py index c06ca9b..8ea6e21 100644 --- a/calibrationSuite/Stats.py +++ b/calibrationSuite/Stats.py @@ -1,40 +1,42 @@ import numpy import logging + logger = logging.getLogger(__name__) + class Stats(object): def __init__(self, shape): self._n = 0 - self._x = numpy.zeros(shape)##, dtype=double) - self._xx = numpy.zeros(shape)##, dtype=double) - self._xy = numpy.zeros(shape)##, dtype=double) + self._x = numpy.zeros(shape) ##, dtype=double) + self._xx = numpy.zeros(shape) ##, dtype=double) + self._xy = numpy.zeros(shape) ##, dtype=double) def mean(self): - return self._x/self._n + return self._x / self._n def rms(self): - return ((self._xx/self._n - (self._x/self._n)**2)).clip(0)**0.5 + return ((self._xx / self._n - (self._x / self._n) ** 2)).clip(0) ** 0.5 def corr(self, yMean, ySigma): -## return (self._xy -self._x*yMean)/self._n - if ySigma >0: + ## return (self._xy -self._x*yMean)/self._n + if ySigma > 0: rmsPosDef = self.rms().clip(0.000001, self.rms().max()) - return numpy.double((self._xy -self._x*yMean)/(self._n*ySigma*rmsPosDef)) + return numpy.double((self._xy - self._x * yMean) / (self._n * ySigma * rmsPosDef)) else: return None def accumulate(self, x, y=0): self._n += 1 self._x += x - self._xx += x*x - self._xy += x*y + self._xx += x * x + self._xy += x * y + - -if __name__ == '__main__': +if __name__ == "__main__": a = numpy.zeros([10]) s = Stats(a.shape) for i in range(10000): - d = numpy.sin((numpy.array(list(range(10)))+i)/3.14159) + d = numpy.sin((numpy.array(list(range(10))) + i) / 3.14159) s.accumulate(d, d[7]) print("mean: " + str(s.mean())) @@ -42,4 +44,4 @@ def accumulate(self, x, y=0): print("s.corr(s.mean()[7], s.rms()[7]): " + str(s.corr(s.mean()[7], s.rms()[7]))) logger.info("mean: " + str(s.mean())) logger.info("rms: " + str(s.rms())) - logger.info("s.corr(s.mean()[7], s.rms()[7]): " + str(s.corr(s.mean()[7], s.rms()[7]))) \ No newline at end of file + logger.info("s.corr(s.mean()[7], s.rms()[7]): " + str(s.corr(s.mean()[7], s.rms()[7]))) diff --git a/calibrationSuite/ancillaryMethods.py b/calibrationSuite/ancillaryMethods.py index 03ddb36..db80ff6 100644 --- a/calibrationSuite/ancillaryMethods.py +++ b/calibrationSuite/ancillaryMethods.py @@ -1,54 +1,59 @@ import numpy as np from scipy.stats import binned_statistic import logging + logger = logging.getLogger(__name__) + def makeProfile(x, y, bins, range=None, spread=False): ## NaN for empty bins are suppressed ## using mean root(N) for non-empty bins to calculate 0 var weights ## ## spread=True to return standard deviation instead of standard error - meansObj = binned_statistic(x, [y, y**2], bins=bins, range=range, statistic='mean') + meansObj = binned_statistic(x, [y, y**2], bins=bins, range=range, statistic="mean") means, means2 = meansObj.statistic - countsObj = binned_statistic(x, y, bins=bins, range=range, statistic='count') - stdObj = binned_statistic(x, y, bins=bins, range=range, statistic='std') + countsObj = binned_statistic(x, y, bins=bins, range=range, statistic="count") + stdObj = binned_statistic(x, y, bins=bins, range=range, statistic="std") bin_N = countsObj.statistic - usefulBins = np.bitwise_and(bin_N>0, ~np.isnan(means)) - if bin_N.sum()==0: + usefulBins = np.bitwise_and(bin_N > 0, ~np.isnan(means)) + if bin_N.sum() == 0: ##no data print("no data in profile") logger.error("no data in profile") return None, None, None - + ##yErr = np.sqrt(means2 - means**2) yErr = stdObj.statistic if not spread: root_N = np.sqrt(bin_N) - root_N[root_N==0] = root_N[usefulBins].mean() - yErr = yErr/root_N + root_N[root_N == 0] = root_N[usefulBins].mean() + yErr = yErr / root_N ##yErr = yErr.clip(0, 6666666.) bin_edges = meansObj.bin_edges - bin_centers = (bin_edges[:-1] + bin_edges[1:])/2. + bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2.0 return bin_centers[usefulBins], means[usefulBins], yErr[usefulBins] + def plotProfile(x, y, yErr): - plt.errorbar(x=x, y=y, yerr=yErr, linestyle='none', marker='.') + plt.errorbar(x=x, y=y, yerr=yErr, linestyle="none", marker=".") + def selectedClusters(clusters, row, col, lowEnerygCut, highEnergyCut, nPixelCut=4, isSquare=1): pass + def goodClusters(clusters, row, col, nPixelCut=4, isSquare=None): ##print(clusters) - pixelRowCol = np.bitwise_and((clusters[:,:,1] == row), - (clusters[:,:,2] == col)) + pixelRowCol = np.bitwise_and((clusters[:, :, 1] == row), (clusters[:, :, 2] == col)) if isSquare is None: - small = clusters[:,:,3] 0.999: - ##print(b, frame[r, colOffset:colOffset + self.detColsPerBank], rowCM, rowCM 0.999: - ##print(frame[r, colOffset:colOffset + self.detColsPerBank], np.median(frame[r, colOffset:colOffset + self.detColsPerBank])) + ##print(frame[r, colOffset:colOffset + self.detColsPerBank], np.median(frame[r, colOffset:colOffset + self.detColsPerBank])) except: rowCM = -666 print("rowCM problem") logger.error("rowCM problem") - print(frame[r, colOffset:colOffset + self.detColsPerBank]) + print(frame[r, colOffset : colOffset + self.detColsPerBank]) colOffset += self.detColsPerBank return frame - + def colCommonModeCorrection(self, frame, arbitraryCut=1000): ## this takes a 2d frame ## cut keeps photons in common mode - e.g. set to <<1 photon @@ -247,20 +249,24 @@ def colCommonModeCorrection(self, frame, arbitraryCut=1000): for c in range(self.detCols): rowOffset = 0 for b in range(0, self.detNbanksCol): - ##for b in range(0, 2): + ##for b in range(0, 2): try: - colCM = np.median(frame[rowOffset:rowOffset + self.detRowsPerBank, c][frame[rowOffset:rowOffset + self.detRowsPerBank, c] 0.999: - ##print(b, frame[r, colOffset:colOffset + self.detColsPerBank], rowCM, rowCM 0.999: - ##print(frame[r, colOffset:colOffset + self.detColsPerBank], np.median(frame[r, colOffset:colOffset + self.detColsPerBank])) + ##print(frame[r, colOffset:colOffset + self.detColsPerBank], np.median(frame[r, colOffset:colOffset + self.detColsPerBank])) except: colCM = -666 print("colCM problem") logger.error("colCM problem") - print(frame[rowOffset:rowOffset + self.detRowsPerBank], c) + print(frame[rowOffset : rowOffset + self.detRowsPerBank], c) rowOffset += self.detRowsPerBank return frame @@ -279,17 +285,15 @@ def isBeamEvent(self, evt): return False def dumpEventCodeStatistics(self): - print("have counted %d run triggers, %d DAQ triggers, %d beam events" - %(self.nRunCodeEvents, - self.nDaqCodeEvents, - self.nBeamCodeEvents) - ) - logger.info("have counted %d run triggers, %d DAQ triggers, %d beam events" - %(self.nRunCodeEvents, - self.nDaqCodeEvents, - self.nBeamCodeEvents) - ) - + print( + "have counted %d run triggers, %d DAQ triggers, %d beam events" + % (self.nRunCodeEvents, self.nDaqCodeEvents, self.nBeamCodeEvents) + ) + logger.info( + "have counted %d run triggers, %d DAQ triggers, %d beam events" + % (self.nRunCodeEvents, self.nDaqCodeEvents, self.nBeamCodeEvents) + ) + if __name__ == "__main__": bSS = BasicSuiteScript() @@ -299,4 +303,3 @@ def dumpEventCodeStatistics(self): evt = bSS.getEvt() print(dir(evt)) logger.info(dir(evt)) - diff --git a/calibrationSuite/cluster.py b/calibrationSuite/cluster.py index b0bbe93..cc27391 100755 --- a/calibrationSuite/cluster.py +++ b/calibrationSuite/cluster.py @@ -1,7 +1,9 @@ import numpy import logging + logger = logging.getLogger(__name__) + class Cluster(object): def __init__(self, row, col, energy): self.seedCol = col @@ -15,48 +17,50 @@ def __init__(self, row, col, energy): self.goodCluster = True self.clusterSide = 3 self.pixelE = numpy.zeros((self.clusterSide, self.clusterSide)) - + self.addPixel(0, 0, energy) self.eTotalNoCuts += energy def addPixel(self, offsetR, offsetC, energy): self.nPixels += 1 - if (energy>self.seedEnergy): self.goodCluster = False + if energy > self.seedEnergy: + self.goodCluster = False self.eTotal += energy - self.pixelE[offsetR+1, offsetC+1] = energy ## pixel seed in 1, 1; corner in -1, -1; etc. - + self.pixelE[offsetR + 1, offsetC + 1] = energy ## pixel seed in 1, 1; corner in -1, -1; etc. + def blindlyNoteEnergy(self, energy): self.eTotalNoCuts += energy ## add to pixel list or array or something - if (energy>self.eSecondaryPixelNoCuts): self.eSecondaryPixelNoCuts = energy + if energy > self.eSecondaryPixelNoCuts: + self.eSecondaryPixelNoCuts = energy def centroid(self): weightedC = 0 weightedR = 0 - + for i in range(3): for j in range(3): - weightedR += self.pixelE[i, j]*(i+0.5) - weightedC += self.pixelE[i, j]*(j+0.5) - c = weightedC/self.eTotal - 1.5 + self.seedCol - r = weightedR/self.eTotal - 1.5 + self.seedRow + weightedR += self.pixelE[i, j] * (i + 0.5) + weightedC += self.pixelE[i, j] * (j + 0.5) + c = weightedC / self.eTotal - 1.5 + self.seedCol + r = weightedR / self.eTotal - 1.5 + self.seedRow return (r, c) def isSquare(self): - if (self.nPixels==1): return True - if (self.nPixels==2): - if (self.pixelE[0, 0]!=0 or - self.pixelE[0, 2]!=0 or - self.pixelE[2, 0]!=0 or - self.pixelE[2, 2]!=0): return False + if self.nPixels == 1: + return True + if self.nPixels == 2: + if self.pixelE[0, 0] != 0 or self.pixelE[0, 2] != 0 or self.pixelE[2, 0] != 0 or self.pixelE[2, 2] != 0: + return False return True - if (self.nPixels<5): - rowSum0 = (self.pixelE[0, 0]==0) and (self.pixelE[0, 1]==0) and (self.pixelE[0, 2]==0) - rowSum2 = (self.pixelE[2, 0]==0) and (self.pixelE[2, 1]==0) and (self.pixelE[2, 2]==0) - colSum0 = (self.pixelE[0, 0]==0) and (self.pixelE[1, 0]==0) and (self.pixelE[2, 0]==0) - colSum2 = (self.pixelE[0, 2]==0) and (self.pixelE[1, 2]==0) and (self.pixelE[2, 2]==0) + if self.nPixels < 5: + rowSum0 = (self.pixelE[0, 0] == 0) and (self.pixelE[0, 1] == 0) and (self.pixelE[0, 2] == 0) + rowSum2 = (self.pixelE[2, 0] == 0) and (self.pixelE[2, 1] == 0) and (self.pixelE[2, 2] == 0) + colSum0 = (self.pixelE[0, 0] == 0) and (self.pixelE[1, 0] == 0) and (self.pixelE[2, 0] == 0) + colSum2 = (self.pixelE[0, 2] == 0) and (self.pixelE[1, 2] == 0) and (self.pixelE[2, 2] == 0) ## could demand no corner energy for 3-pixel clusters - if ((rowSum0 or rowSum2) and (colSum0 or colSum2)): return True + if (rowSum0 or rowSum2) and (colSum0 or colSum2): + return True return False def maskedNeighbor(self): @@ -72,19 +76,19 @@ def __init__(self, frame, seedCut, neighborCut): def findClusters(self): clusters = [] rows, cols = self.frame.shape - for r in range(1, rows-1): - for c in range(1, cols-1): - if self.frame[r, c]self.neighborCut: + if i == 0 and j == 0: + continue + en = self.frame[r + i, c + j] + cluster.blindlyNoteEnergy(en) + if en > self.neighborCut: cluster.addPixel(i, j, en) if cluster.goodCluster: clusters.append(cluster) return clusters - diff --git a/calibrationSuite/fitFunctions.py b/calibrationSuite/fitFunctions.py index 268210c..2a4f098 100644 --- a/calibrationSuite/fitFunctions.py +++ b/calibrationSuite/fitFunctions.py @@ -3,67 +3,80 @@ from scipy.stats import norm from statsmodels.nonparametric.bandwidths import bw_silverman import logging + logger = logging.getLogger(__name__) + def linear(x, a, b): - return a*x + b + return a * x + b + def saturatedLinear(x, a, b, c, d): - return [a*X + b if X < c else d for X in x] + return [a * X + b if X < c else d for X in x] + def saturatedLinearB(x, a, b, d): - return [a*X + b if a*X+b < d else d for X in x] + return [a * X + b if a * X + b < d else d for X in x] + def gaussian(x, a, mu, sigma): - return a*np.exp(-(x-mu)**2/(2*sigma**2)) + return a * np.exp(-((x - mu) ** 2) / (2 * sigma**2)) + def gaussianArea(a, sigma): return a * sigma * 6.28 + def estimateGaussianParametersFromUnbinnedArray(flatData): sigma = flatData.std() entries = len(flatData) ## will crash if sigma is 0 - return entries/(sigma*6.28), flatData.mean(), sigma + return entries / (sigma * 6.28), flatData.mean(), sigma + def estimateGaussianParametersFromXY(x, y): mean, sigma = getHistogramMeanStd(x, y) ## will crash if sigma is 0 - return sum(y)/(sigma*6.28), mean, sigma + return sum(y) / (sigma * 6.28), mean, sigma + def getHistogramMeanStd(binCenters, counts): mean = np.average(binCenters, weights=counts) - var = np.average((binCenters - mean)**2, weights=counts) + var = np.average((binCenters - mean) ** 2, weights=counts) return mean, np.sqrt(var) + def calculateFitR2(y, fit): ss_res = np.sum((y - fit) ** 2) ss_tot = np.sum((y - np.mean(y)) ** 2) - + try: r2 = 1 - (ss_res / ss_tot) except: - r2 = 1 ## I guess + r2 = 1 ## I guess return r2 + def getBinCentersFromNumpyHistogram(bins): - return (bins[1:] + bins[:-1])/2. + return (bins[1:] + bins[:-1]) / 2.0 + def getRestrictedHistogram(bins, counts, x0, x1): - cut = np.where(np.logical_and(bins>=x0, bins<=x1)) + cut = np.where(np.logical_and(bins >= x0, bins <= x1)) x = bins[cut] y = counts[cut] return x, y + def getGaussianFitFromHistogram(binCenters, counts, x0=None, x1=None): ## binned 1d data, optional fit restriction to [x0, x1] x = binCenters y = counts if x0 is not None: x, y = getRestrictedHistogram(x, y, x0, x1) - - a, mean, std = estimateGaussianParameters(zip(x,y)) + + a, mean, std = estimateGaussianParameters(zip(x, y)) popt, pcov = curve_fit(gaussian, x, y, [3, mean, std]) ##a = popt[0] ##mu = popt[1] @@ -72,7 +85,8 @@ def getGaussianFitFromHistogram(binCenters, counts, x0=None, x1=None): ## should perhaps return an object with attributes for future flexibility return popt, fittedFunc - + + def fitNorm(data): mean, std = norm.fit(data) return mean, std @@ -85,12 +99,14 @@ def twoGaussSilvermanModeTest(x0, x1): d = np.append(b, c) if False: import matplotlib.pyplot as plt + plt.hist(d, 100) ##plt.hist(a, 100) plt.show() print(a.mean(), a.std(), d.mean(), d.std()) print(x0, x1, bw_silverman(a), bw_silverman(d)) - return d.std()/a.std(), bw_silverman(d)/bw_silverman(a) + return d.std() / a.std(), bw_silverman(d) / bw_silverman(a) + def testSilvermanModeTest(): a = np.linspace(0, 3, 10) @@ -102,43 +118,44 @@ def testSilvermanModeTest(): S.append(r1) import matplotlib.pyplot as plt + plt.plot(noise, S) plt.title("Two gaussian test of Silverman's test separating peaks") plt.xlabel("two peak rms/one peak rms") plt.ylabel("two peak Silverman/one peak Silverman") plt.show() - + a = np.random.normal(0, 100, 1000) b = np.random.normal(0, 100, 10000) - c = np.where(b!=50) + c = np.where(b != 50) print("rms for a gap in gaussian, notched gaussian:", a.std(), b[c][:1000].std()) print("Silverman for a gap in gaussian, notched gaussian:", bw_silverman(a), bw_silverman(b[c][:1000])) - print("rms for a gap in gaussian/notched gaussian:", a.std()/b[c][:1000].std()) - print("Silverman for a gap in gaussian/notched gaussian:", bw_silverman(a)/bw_silverman(b[c][:1000])) + print("rms for a gap in gaussian/notched gaussian:", a.std() / b[c][:1000].std()) + print("Silverman for a gap in gaussian/notched gaussian:", bw_silverman(a) / bw_silverman(b[c][:1000])) + - def missingBinTest(binCenters, counts): mu, sigma = getHistogramMeanStd(binCenters, counts) - binCenters, counts = getRestrictedHistogram(binCenters, counts, mu-sigma, mu+sigma) + binCenters, counts = getRestrictedHistogram(binCenters, counts, mu - sigma, mu + sigma) ##print(len(b), len(c)) n = len(counts) - if n>=10: - step = int(n/10) + if n >= 10: + step = int(n / 10) else: step = n - + cuts = range(1, 6) missingBins = np.zeros(len(cuts)) - + for i in range(step): - i0 = step*i - i1 = min(step*(i+1), n) + i0 = step * i + i1 = min(step * (i + 1), n) med = np.median(counts[i0:i1]) mean = counts[i0:i1].mean() rootN = np.sqrt(mean) for k in cuts: for j in range(i0, i1): - if counts[j](missingValue+1), b (missingValue + 1), b < missingValue)) b = b[c][:nSamples] ##print(50 in a, 50 in b) ha, bins = np.histogram(a, 600, [-300, 300]) - hb,_ = np.histogram(b, 600, [-300, 300]) + hb, _ = np.histogram(b, 600, [-300, 300]) binCenters = getBinCentersFromNumpyHistogram(bins) ##print(binCenters, ha, hb) if True: import matplotlib.pyplot as plt + plt.stairs(ha, bins) - plt.stairs(hb, bins, color='b') + plt.stairs(hb, bins, color="b") plt.show() mbt_a = missingBinTest(binCenters, ha) mbt_b = missingBinTest(binCenters, hb) print("per n sigma check for gap in gaussian, notched gaussian:", mbt_a, mbt_b) - print((range(1,6)*mbt_a).sum(), (range(1,6)*mbt_b).sum()) \ No newline at end of file + print((range(1, 6) * mbt_a).sum(), (range(1, 6) * mbt_b).sum()) diff --git a/calibrationSuite/loggingSetup.py b/calibrationSuite/loggingSetup.py index 6b0f453..90a3b65 100644 --- a/calibrationSuite/loggingSetup.py +++ b/calibrationSuite/loggingSetup.py @@ -1,11 +1,12 @@ import logging + def setupScriptLogging(fileName, logLevel): # Setup logging to file '.log', and configures the underlying calibration-library logging. # Log file gets appended to each new run, and can manually delete for fresh log. # (Could change so makes new unique log each run or overwrites existing log) logging.basicConfig( - filename= fileName, - level=logLevel, # For full logging set to INFO which includes ERROR logging too - format='%(asctime)s - %(levelname)s - %(message)s' # levelname is log severity (ERROR, INFO, etc) - ) \ No newline at end of file + filename=fileName, + level=logLevel, # For full logging set to INFO which includes ERROR logging too + format="%(asctime)s - %(levelname)s - %(message)s", # levelname is log severity (ERROR, INFO, etc) + ) diff --git a/calibrationSuite/psana1Base.py b/calibrationSuite/psana1Base.py index bfe4281..cf8cf57 100755 --- a/calibrationSuite/psana1Base.py +++ b/calibrationSuite/psana1Base.py @@ -1,36 +1,37 @@ from psana import * from PSCalib.NDArrIO import load_txt import logging + logger = logging.getLogger(__name__) + class PsanaBase(object): - def __init__(self, analysisType='scan'): + def __init__(self, analysisType="scan"): self.psanaType = 1 print("in psana1Base") logger.info("in psana1Base") - self.gainModes = {"FH":0, "FM":1, "FL":2, "AHL-H":3, "AML-M":4, "AHL-L":5, "AML-L":6} - self.ePix10k_cameraTypes = {1:"Epix10ka", 4:"Epix10kaQuad", 16:"Epix10ka2M"} - self.g0cut = 1<<14 + self.gainModes = {"FH": 0, "FM": 1, "FL": 2, "AHL-H": 3, "AML-M": 4, "AHL-L": 5, "AML-L": 6} + self.ePix10k_cameraTypes = {1: "Epix10ka", 4: "Epix10kaQuad", 16: "Epix10ka2M"} + self.g0cut = 1 << 14 self.gainBitsMask = self.g0cut - 1 -## self.setupPsana() + ## self.setupPsana() def get_ds(self, run=None): if run is None: run = self.run - return DataSource('exp=%s:run=%d:smd' %(self.exp, run)) - + return DataSource("exp=%s:run=%d:smd" % (self.exp, run)) def setupPsana(self): - logger.info("have built basic script class, exp %s run %d" %(self.exp, self.run)) + logger.info("have built basic script class, exp %s run %d" % (self.exp, self.run)) if self.runRange is None: self.ds = self.get_ds(self.run) else: self.run = self.runRange[0] self.ds = self.get_ds() - - self.det = Detector('%s.0:%s.%d' %(self.location, self.detType, self.camera), self.ds.env()) + + self.det = Detector("%s.0:%s.%d" % (self.location, self.detType, self.camera), self.ds.env()) self.evrs = None try: self.wave8 = Detector(self.fluxSource, self.ds.env()) @@ -38,10 +39,10 @@ def setupPsana(self): self.wave8 = None self.config = None try: - self.controlData = Detector('ControlData') + self.controlData = Detector("ControlData") except: self.controlData = None - + def getFivePedestalRunInfo(self): ## could do load_txt but would require full path so if self.det is None: @@ -50,14 +51,14 @@ def getFivePedestalRunInfo(self): evt = self.getEvt(self.fivePedestalRun) self.fpGains = self.det.gain(evt) self.fpPedestals = self.det.pedestals(evt) - self.fpStatus = self.det.status(evt)## does this work? - self.fpRMS = self.det.rms(evt)## does this work? - + self.fpStatus = self.det.status(evt) ## does this work? + self.fpRMS = self.det.rms(evt) ## does this work? + def getEvt(self, run=None): oldDs = self.ds if run is not None: self.ds = self.get_ds(run) - try:## or just yield evt I think + try: ## or just yield evt I think evt = next(self.ds.events()) except StopIteration: self.ds = oldDs @@ -65,7 +66,6 @@ def getEvt(self, run=None): self.ds = oldDs return evt - def getEvtFromRunsTooSmartForMyOwnGood(self): for r in self.runRange: self.run = r @@ -77,15 +77,15 @@ def getEvtFromRunsTooSmartForMyOwnGood(self): continue def getEvtFromRuns(self): - try:## can't get yield to work + try: ## can't get yield to work evt = next(self.ds.events()) - return(evt) + return evt except StopIteration: i = self.runRange.index(self.run) try: - self.run = self.runRange[i+1] - print("switching to run %d" %(self.run)) - logger.info("switching to run %d" %(self.run)) + self.run = self.runRange[i + 1] + print("switching to run %d" % (self.run)) + logger.info("switching to run %d" % (self.run)) self.ds = self.get_ds(self.run) except: print("have run out of new runs") @@ -94,17 +94,17 @@ def getEvtFromRuns(self): ##print("get event from new run") evt = next(self.ds.events()) return evt - + def getFlux(self, evt): try: fluxes = self.wave8.get(evt).peakA() if fluxes is None: - print("No flux found")## if self.verbose? + print("No flux found") ## if self.verbose? logger.error("No flux found") return None - f = fluxes[self.fluxChannels].mean()*self.fluxSign + f = fluxes[self.fluxChannels].mean() * self.fluxSign try: - if f0 - + return delta > 0 + + if __name__ == "__main__": bSS = BasicSuiteScript() print("have built a BasicSuiteScript") bSS.setupPsana() evt = bSS.getEvt() print(dir(evt)) -