#!/usr/bin/env python
import numpy as np
import pandas, os
from tensorflow.keras.models import Model
from tensorflow.keras.layers import *
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.utils import plot_model
from tensorflow.keras import backend as K
from tensorflow.keras.callbacks import CSVLogger,EarlyStopping
from PixelateHistogram import *
from scipy.special import gammainc, gammaincc, erfinv
from scipy.stats import norm
import matplotlib.pyplot as plt
from PixelateHistogram.losses import Significance
from PixelateHistogram.layers import *

def getModel_AE(nBINS):
	input_layer = Input(shape=(nBINS,1))
	yields    = Lambda(lambda x: K.sum(x, axis=1), name="compute_yields")(input_layer)
	yieldsInv = Lambda(lambda x: 1./K.sum(x, axis=1), name="compute_yieldsInv")(input_layer)
	
	input_layer1=Dot(axes=[-1,-1])([input_layer, yieldsInv])
	dense = Reshape((nBINS,))(input_layer1)
	#dense   = Dense(units=nBINS, activation='relu',    kernel_initializer='uniform', bias_initializer='zeros') (dense)
	#dense   = Dense(units=50,    activation='relu',    kernel_initializer='uniform', bias_initializer='zeros') (dense)
	dense   = Dense(units=200,    activation='relu',    kernel_initializer='uniform', bias_initializer='zeros') (dense)
	#dense   = Dense(units=8,     activation='relu',    kernel_initializer='uniform', bias_initializer='zeros') (dense)
	dense   = Dense(units=30,     activation='relu',    kernel_initializer='uniform', bias_initializer='zeros') (dense)
	#dense   = Dense(units=50,     activation='relu',    kernel_initializer='uniform', bias_initializer='zeros') (dense)
	dense   = Dense(units=200,     activation='relu',    kernel_initializer='uniform', bias_initializer='zeros') (dense)
	softmax   = Dense(units=nBINS, activation='softmax', kernel_initializer='uniform', bias_initializer='zeros') (dense)
	#softmax = Softmax() (dense)
	predictions = Reshape((nBINS,1))(softmax)  
	
	predictions_rescaled=Dot(axes=[-1,-1])([predictions, yields])
	
	model = Model(inputs=input_layer, outputs=predictions_rescaled)
	model.compile(loss=Significance, optimizer=RMSprop(lr=1e-4))
	
	modelDir= 'output_AE'
	os.system('mkdir -p '+modelDir)
	
	return model,modelDir
	
	
def getModel_Pixelate(nBINS, n_sigma=0):
	input_layer = Input(shape=(nBINS,1))
	yields = Lambda(lambda x: K.sum(x, axis=1), name="compute_yields")(input_layer)
	
	print ('input_layer', input_layer.shape)
	
	
	pixels = PixelateLayer(stepSize=0.01, n_sigma=n_sigma, flatten=True)(input_layer)
	
	dense   = Dense(units=nBINS, activation='relu', kernel_initializer='uniform', bias_initializer='zeros', name="dense0") (pixels)
	softmax   = Dense(units=nBINS, activation='softmax', kernel_initializer='uniform', bias_initializer='zeros', name="softmax") (dense)
	predictions = Reshape((nBINS,1))(softmax)
	
	predictions_rescaled=Dot(axes=[-1,-1])([predictions, yields])
	
	model = Model(inputs=input_layer, outputs=predictions_rescaled)
	model.compile(loss=Significance, optimizer=RMSprop(lr=1e-4))
	
	modelDir= 'output_Pixelate_'+str(n_sigma)
	os.system('mkdir -p '+modelDir)
	
	return model,modelDir

def getModel_PixelateNoise(nBINS, n_sigma=0):
	input_layer = Input(shape=(nBINS,1))
	input_layer2 = PoissonianNoise()(input_layer)
	yields = Lambda(lambda x: K.sum(x, axis=1), name="compute_yields")(input_layer2)
	
	pixels = PixelateLayer(stepSize=0.01, n_sigma=n_sigma, flatten=True)(input_layer2)
	
	dense   = Dense(units=nBINS, activation='relu', kernel_initializer='uniform', bias_initializer='zeros', name="dense0") (pixels)
	softmax   = Dense(units=nBINS, activation='softmax', kernel_initializer='uniform', bias_initializer='zeros', name="softmax") (dense)
	predictions = Reshape((nBINS,1))(softmax)
	
	predictions_rescaled=Dot(axes=[-1,-1])([predictions, yields])
	
	model = Model(inputs=input_layer, outputs=predictions_rescaled)
	model.compile(loss=Significance, optimizer=RMSprop(lr=1e-4))
	
	modelDir= 'output_PixelateNoise_'+str(n_sigma)
	os.system('mkdir -p '+modelDir)
	
	return model,modelDir
	
def recoverTruth(modelName, dataDirectory):
	BINS = pandas.read_csv(dataDirectory+'/bins.csv',header=None)
	print (BINS)
	
	nBINS=np.size(BINS)-1
	print(nBINS)
	
	if modelName=="AE":       model,modelDir = getModel_AE(nBINS)
	if modelName=="Pixelate_0": model,modelDir = getModel_Pixelate(nBINS)
	if modelName=="Pixelate_1": model,modelDir = getModel_Pixelate(nBINS,1)
	if modelName=="Pixelate_2": model,modelDir = getModel_Pixelate(nBINS,2)
	if modelName=="PixelateNoise_0": model,modelDir = getModel_PixelateNoise(nBINS)
	
	model.build(input_shape=(nBINS,))
	model.summary()
	plot_model(model, to_file=modelDir+'/model.png', show_shapes=True)
	
	Xtrain = pandas.read_csv(dataDirectory+'/data_train.csv',header=None).values  # pseudo-data histograms
	Ytrain = pandas.read_csv(dataDirectory+'/model_train.csv',header=None).values # truth pdf histograms
	Xtest  = pandas.read_csv(dataDirectory+'/data_test.csv',header=None).values   # pseudo-data histograms
	Ytest  = pandas.read_csv(dataDirectory+'/model_test.csv',header=None).values  # truth pdf histograms
	
	if modelName=="PixelateNoise_0": Xtrain=Ytrain # in that case, Poisson noise is added on top of truth, on the fly, only during training
	
	history =model.fit(x=Xtrain, y=Ytrain, validation_data=(Xtest,Ytest), batch_size=128, epochs=1000, verbose=1, callbacks=[CSVLogger(modelDir+'/training.log'), EarlyStopping(patience=3)])
	
	Ypred = model.predict(Xtest)
	
	
	fileName = modelDir+"/result.csv"
	np.savetxt(fileName, Ypred, delimiter=",")
	
	return

def significance(d, b, sigma):
	epsilon=1e-12
	if d>=b:
		poisson = gammainc(d,b) 
		poisson = min(max(poisson, epsilon), 1-epsilon)
		sigma = np.sqrt(2.)*erfinv(1-2*poisson)
	elif d>0 :
		poisson = gammaincc(d,b)
		poisson = min(max(poisson, epsilon), 1-epsilon)
		sigma = -np.sqrt(2.)*erfinv(1-2*poisson)
	else: sigma=0
	return sigma
	
def displayResults(dataDirectory, modelDir, nrows=1000):
	
	BINS = pandas.read_csv(dataDirectory+'/bins.csv',header=None)
	Xtest= pandas.read_csv(dataDirectory+'/data_test.csv',header=None, nrows=nrows).values  # pseudo-data histograms
	Ytest= pandas.read_csv(dataDirectory+'/model_test.csv',header=None, nrows=nrows).values  # truth pdf histograms
	YtestEstimate= pandas.read_csv(modelDir+'/result.csv',header=None, nrows=nrows).values  # infered pdf histograms
	
	#Ytest_sigma= np.sqrt(Ytest)
	signif_data = [[ significance(x, mu, np.sqrt(mu)) for (x, mu) in zip(lineX, lineMu)]for (lineX, lineMu) in zip(Xtest, Ytest)]
	signif_estimate = [[ significance(x, mu, np.sqrt(mu)) for (x, mu) in zip(lineX, lineMu)]for (lineX, lineMu) in zip(YtestEstimate, Ytest)]
	#print (signif_data)
	#print (signif_estimate)
	
	signif_data0=np.reshape(signif_data, (-1))
	signif_estimate0=np.reshape(signif_estimate, (-1))
	
	plt.hist(signif_data0, density=False, bins=100)
	plt.savefig(modelDir+'/residual_data_truth.png')
	plt.close()
	
	plt.hist(signif_estimate0, density=False, bins=100)
	plt.savefig(modelDir+'/residual_estimate_truth.png')
	plt.close()
	
	Range = [-5,5]

	n, bins, patches = plt.hist(signif_estimate0, density=False, bins=50, range=Range, label='Z(output, truth)')
	n, bins, patches = plt.hist(signif_data0,   density=False, bins=bins, range=Range, label='Z(data, truth)', hatch='=', edgecolor='r', facecolor="None", histtype = 'step')
	plt.legend()
	
	
	#(mu, sigma) = norm.fit(signif_estimate0)
	#print(mu,sigma)
	#rms = np.sqrt(np.mean(signif_estimate0**2))
	#print(rms)
	
	
	#y = norm.pdf( bins, mu, sigma)
	#l = plt.plot(bins, y, 'r--', linewidth=2)
	#(mu, sigma) = norm.fit(signif_data0)
	#print('mu',mu,'\tsigma',sigma)
	#rms = np.sqrt(np.mean(signif_data0**2))
	#print('rms',rms)
	
	plt.savefig(modelDir+'/residuals.png')
	plt.savefig(modelDir+'/residuals.pdf')
	plt.close()
	return
	
def displayResults2(dataDirectory, modelDirPx, modelDirAE, nrows=1000):
	
	BINS = pandas.read_csv(dataDirectory+'/bins.csv',header=None)
	Xtest= pandas.read_csv(dataDirectory+'/data_test.csv',header=None, nrows=nrows).values  # pseudo-data histograms
	Ytest= pandas.read_csv(dataDirectory+'/model_test.csv',header=None, nrows=nrows).values  # truth pdf histograms
	YtestEstimatePx= pandas.read_csv(modelDirPx+'/result.csv',header=None, nrows=nrows).values  # infered pdf histograms
	YtestEstimateAE= pandas.read_csv(modelDirAE+'/result.csv',header=None, nrows=nrows).values  # infered pdf histograms
	
	#Ytest_sigma= np.sqrt(Ytest)
	signif_data = [[ significance(x, mu, np.sqrt(mu)) for (x, mu) in zip(lineX, lineMu)]for (lineX, lineMu) in zip(Xtest, Ytest)]
	signif_estimatePx = [[ significance(x, mu, np.sqrt(mu)) for (x, mu) in zip(lineX, lineMu)]for (lineX, lineMu) in zip(YtestEstimatePx, Ytest)]
	signif_estimateAE = [[ significance(x, mu, np.sqrt(mu)) for (x, mu) in zip(lineX, lineMu)]for (lineX, lineMu) in zip(YtestEstimateAE, Ytest)]
	#print (signif_data)
	#print (signif_estimate)
	
	signif_data0=np.reshape(signif_data, (-1))
	signif_estimatePx0=np.reshape(signif_estimatePx, (-1))
	signif_estimateAE0=np.reshape(signif_estimateAE, (-1))
	
	
	Range = [-5,5]

	n, bins, patches = plt.hist(signif_data0,   density=False, bins=50, range=Range, label='Z(data, truth)' , facecolor="blue")
	n, bins, patches = plt.hist(signif_estimatePx0, density=False, bins=50, range=Range, label='Z( pixNN(data), truth)', hatch='=', edgecolor='r', facecolor="None", histtype = 'step')
	n, bins, patches = plt.hist(signif_estimateAE0, density=False, bins=50, range=Range, label='Z( aeNN(data), truth)', hatch='=', edgecolor='g', facecolor="None", histtype = 'step')
	plt.xlim(Range)
	plt.xlabel("Bin-by-bin residuals")

	plt.legend()
	
	
	#(mu, sigma) = norm.fit(signif_estimate0)
	#print(mu,sigma)
	#rms = np.sqrt(np.mean(signif_estimate0**2))
	#print(rms)
	
	
	#y = norm.pdf( bins, mu, sigma)
	#l = plt.plot(bins, y, 'r--', linewidth=2)
	#(mu, sigma) = norm.fit(signif_data0)
	#print('mu',mu,'\tsigma',sigma)
	#rms = np.sqrt(np.mean(signif_data0**2))
	#print('rms',rms)
	
	plt.savefig('residuals.png')
	plt.savefig('residuals.pdf')
	plt.close()
	
	return

#recoverTruth(modelName="AE",       dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/")
recoverTruth(modelName="Pixelate_0", dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/")
#recoverTruth(modelName="Pixelate_1", dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/")
#recoverTruth(modelName="Pixelate_2", dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/")
recoverTruth(modelName="PixelateNoise_0", dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/")


displayResults(dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/", modelDir='output_AE')
displayResults(dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/", modelDir='output_Pixelate_0')

displayResults2(dataDirectory="data/SPL-17b_700-1erfexp-v1-normW0.1-Nevt1e5-dupM1/", modelDirPx='output_Pixelate_0', modelDirAE='output_AE')


matplotlib.pyplot.legend numpy.sqrt scipy.special.gammainc scipy.special.erfinv scipy.special.gammaincc pandas.read_csv numpy.reshape tensorflow.keras.optimizers.RMSprop numpy.size matplotlib.pyplot.close tensorflow.keras.callbacks.EarlyStopping tensorflow.keras.models.Model tensorflow.keras.utils.plot_model tensorflow.keras.backend.sum matplotlib.pyplot.savefig tensorflow.keras.callbacks.CSVLogger numpy.savetxt matplotlib.pyplot.hist matplotlib.pyplot.xlim matplotlib.pyplot.xlabel
[(37, 'tensorflow.keras.models.Model', 'Model', ([], {'inputs': 'input_layer', 'outputs': 'predictions_rescaled'}), False, 'from tensorflow.keras.models import Model\n'), (41, 'os.system', 'os.system', (["('mkdir -p ' + modelDir)"], {}), False, 'import pandas, os\n'), (61, 'tensorflow.keras.models.Model', 'Model', ([], {'inputs': 'input_layer', 'outputs': 'predictions_rescaled'}), False, 'from tensorflow.keras.models import Model\n'), (65, 'os.system', 'os.system', (["('mkdir -p ' + modelDir)"], {}), False, 'import pandas, os\n'), (82, 'tensorflow.keras.models.Model', 'Model', ([], {'inputs': 'input_layer', 'outputs': 'predictions_rescaled'}), False, 'from tensorflow.keras.models import Model\n'), (86, 'os.system', 'os.system', (["('mkdir -p ' + modelDir)"], {}), False, 'import pandas, os\n'), (91, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/bins.csv')"], {'header': 'None'}), False, 'import pandas, os\n'), (105, 'tensorflow.keras.utils.plot_model', 'plot_model', (['model'], {'to_file': "(modelDir + '/model.png')", 'show_shapes': '(True)'}), False, 'from tensorflow.keras.utils import plot_model\n'), (120, 'numpy.savetxt', 'np.savetxt', (['fileName', 'Ypred'], {'delimiter': '""","""'}), True, 'import numpy as np\n'), (139, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/bins.csv')"], {'header': 'None'}), False, 'import pandas, os\n'), (150, 'numpy.reshape', 'np.reshape', (['signif_data', '(-1)'], {}), True, 'import numpy as np\n'), (151, 'numpy.reshape', 'np.reshape', (['signif_estimate', '(-1)'], {}), True, 'import numpy as np\n'), (153, 'matplotlib.pyplot.hist', 'plt.hist', (['signif_data0'], {'density': '(False)', 'bins': '(100)'}), True, 'import matplotlib.pyplot as plt\n'), (154, 'matplotlib.pyplot.savefig', 'plt.savefig', (["(modelDir + '/residual_data_truth.png')"], {}), True, 'import matplotlib.pyplot as plt\n'), (155, 'matplotlib.pyplot.close', 'plt.close', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (157, 'matplotlib.pyplot.hist', 'plt.hist', (['signif_estimate0'], {'density': '(False)', 'bins': '(100)'}), True, 'import matplotlib.pyplot as plt\n'), (158, 'matplotlib.pyplot.savefig', 'plt.savefig', (["(modelDir + '/residual_estimate_truth.png')"], {}), True, 'import matplotlib.pyplot as plt\n'), (159, 'matplotlib.pyplot.close', 'plt.close', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (163, 'matplotlib.pyplot.hist', 'plt.hist', (['signif_estimate0'], {'density': '(False)', 'bins': '(50)', 'range': 'Range', 'label': '"""Z(output, truth)"""'}), True, 'import matplotlib.pyplot as plt\n'), (164, 'matplotlib.pyplot.hist', 'plt.hist', (['signif_data0'], {'density': '(False)', 'bins': 'bins', 'range': 'Range', 'label': '"""Z(data, truth)"""', 'hatch': '"""="""', 'edgecolor': '"""r"""', 'facecolor': '"""None"""', 'histtype': '"""step"""'}), True, 'import matplotlib.pyplot as plt\n'), (165, 'matplotlib.pyplot.legend', 'plt.legend', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (181, 'matplotlib.pyplot.savefig', 'plt.savefig', (["(modelDir + '/residuals.png')"], {}), True, 'import matplotlib.pyplot as plt\n'), (182, 'matplotlib.pyplot.savefig', 'plt.savefig', (["(modelDir + '/residuals.pdf')"], {}), True, 'import matplotlib.pyplot as plt\n'), (183, 'matplotlib.pyplot.close', 'plt.close', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (188, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/bins.csv')"], {'header': 'None'}), False, 'import pandas, os\n'), (201, 'numpy.reshape', 'np.reshape', (['signif_data', '(-1)'], {}), True, 'import numpy as np\n'), (202, 'numpy.reshape', 'np.reshape', (['signif_estimatePx', '(-1)'], {}), True, 'import numpy as np\n'), (203, 'numpy.reshape', 'np.reshape', (['signif_estimateAE', '(-1)'], {}), True, 'import numpy as np\n'), (208, 'matplotlib.pyplot.hist', 'plt.hist', (['signif_data0'], {'density': '(False)', 'bins': '(50)', 'range': 'Range', 'label': '"""Z(data, truth)"""', 'facecolor': '"""blue"""'}), True, 'import matplotlib.pyplot as plt\n'), (209, 'matplotlib.pyplot.hist', 'plt.hist', (['signif_estimatePx0'], {'density': '(False)', 'bins': '(50)', 'range': 'Range', 'label': '"""Z( pixNN(data), truth)"""', 'hatch': '"""="""', 'edgecolor': '"""r"""', 'facecolor': '"""None"""', 'histtype': '"""step"""'}), True, 'import matplotlib.pyplot as plt\n'), (210, 'matplotlib.pyplot.hist', 'plt.hist', (['signif_estimateAE0'], {'density': '(False)', 'bins': '(50)', 'range': 'Range', 'label': '"""Z( aeNN(data), truth)"""', 'hatch': '"""="""', 'edgecolor': '"""g"""', 'facecolor': '"""None"""', 'histtype': '"""step"""'}), True, 'import matplotlib.pyplot as plt\n'), (211, 'matplotlib.pyplot.xlim', 'plt.xlim', (['Range'], {}), True, 'import matplotlib.pyplot as plt\n'), (212, 'matplotlib.pyplot.xlabel', 'plt.xlabel', (['"""Bin-by-bin residuals"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (214, 'matplotlib.pyplot.legend', 'plt.legend', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (230, 'matplotlib.pyplot.savefig', 'plt.savefig', (['"""residuals.png"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (231, 'matplotlib.pyplot.savefig', 'plt.savefig', (['"""residuals.pdf"""'], {}), True, 'import matplotlib.pyplot as plt\n'), (232, 'matplotlib.pyplot.close', 'plt.close', ([], {}), True, 'import matplotlib.pyplot as plt\n'), (94, 'numpy.size', 'np.size', (['BINS'], {}), True, 'import numpy as np\n'), (107, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/data_train.csv')"], {'header': 'None'}), False, 'import pandas, os\n'), (108, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/model_train.csv')"], {'header': 'None'}), False, 'import pandas, os\n'), (109, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/data_test.csv')"], {'header': 'None'}), False, 'import pandas, os\n'), (110, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/model_test.csv')"], {'header': 'None'}), False, 'import pandas, os\n'), (127, 'scipy.special.gammainc', 'gammainc', (['d', 'b'], {}), False, 'from scipy.special import gammainc, gammaincc, erfinv\n'), (140, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/data_test.csv')"], {'header': 'None', 'nrows': 'nrows'}), False, 'import pandas, os\n'), (141, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/model_test.csv')"], {'header': 'None', 'nrows': 'nrows'}), False, 'import pandas, os\n'), (142, 'pandas.read_csv', 'pandas.read_csv', (["(modelDir + '/result.csv')"], {'header': 'None', 'nrows': 'nrows'}), False, 'import pandas, os\n'), (189, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/data_test.csv')"], {'header': 'None', 'nrows': 'nrows'}), False, 'import pandas, os\n'), (190, 'pandas.read_csv', 'pandas.read_csv', (["(dataDirectory + '/model_test.csv')"], {'header': 'None', 'nrows': 'nrows'}), False, 'import pandas, os\n'), (191, 'pandas.read_csv', 'pandas.read_csv', (["(modelDirPx + '/result.csv')"], {'header': 'None', 'nrows': 'nrows'}), False, 'import pandas, os\n'), (192, 'pandas.read_csv', 'pandas.read_csv', (["(modelDirAE + '/result.csv')"], {'header': 'None', 'nrows': 'nrows'}), False, 'import pandas, os\n'), (38, 'tensorflow.keras.optimizers.RMSprop', 'RMSprop', ([], {'lr': '(0.0001)'}), False, 'from tensorflow.keras.optimizers import RMSprop\n'), (62, 'tensorflow.keras.optimizers.RMSprop', 'RMSprop', ([], {'lr': '(0.0001)'}), False, 'from tensorflow.keras.optimizers import RMSprop\n'), (83, 'tensorflow.keras.optimizers.RMSprop', 'RMSprop', ([], {'lr': '(0.0001)'}), False, 'from tensorflow.keras.optimizers import RMSprop\n'), (129, 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), True, 'import numpy as np\n'), (129, 'scipy.special.erfinv', 'erfinv', (['(1 - 2 * poisson)'], {}), False, 'from scipy.special import gammainc, gammaincc, erfinv\n'), (131, 'scipy.special.gammaincc', 'gammaincc', (['d', 'b'], {}), False, 'from scipy.special import gammainc, gammaincc, erfinv\n'), (19, 'tensorflow.keras.backend.sum', 'K.sum', (['x'], {'axis': '(1)'}), True, 'from tensorflow.keras import backend as K\n'), (48, 'tensorflow.keras.backend.sum', 'K.sum', (['x'], {'axis': '(1)'}), True, 'from tensorflow.keras import backend as K\n'), (72, 'tensorflow.keras.backend.sum', 'K.sum', (['x'], {'axis': '(1)'}), True, 'from tensorflow.keras import backend as K\n'), (114, 'tensorflow.keras.callbacks.CSVLogger', 'CSVLogger', (["(modelDir + '/training.log')"], {}), False, 'from tensorflow.keras.callbacks import CSVLogger, EarlyStopping\n'), (114, 'tensorflow.keras.callbacks.EarlyStopping', 'EarlyStopping', ([], {'patience': '(3)'}), False, 'from tensorflow.keras.callbacks import CSVLogger, EarlyStopping\n'), (133, 'scipy.special.erfinv', 'erfinv', (['(1 - 2 * poisson)'], {}), False, 'from scipy.special import gammainc, gammaincc, erfinv\n'), (145, 'numpy.sqrt', 'np.sqrt', (['mu'], {}), True, 'import numpy as np\n'), (146, 'numpy.sqrt', 'np.sqrt', (['mu'], {}), True, 'import numpy as np\n'), (195, 'numpy.sqrt', 'np.sqrt', (['mu'], {}), True, 'import numpy as np\n'), (196, 'numpy.sqrt', 'np.sqrt', (['mu'], {}), True, 'import numpy as np\n'), (197, 'numpy.sqrt', 'np.sqrt', (['mu'], {}), True, 'import numpy as np\n'), (20, 'tensorflow.keras.backend.sum', 'K.sum', (['x'], {'axis': '(1)'}), True, 'from tensorflow.keras import backend as K\n'), (133, 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), True, 'import numpy as np\n')]