<commit_before>#!/usr/bin/env python
from __future__ import absolute_import, print_function, division
from future.utils import with_metaclass
import abc

from opsimsummary import Tiling, HealpixTiles
from analyzeSN import LightCurve
from .universe import Universe
from .paramDistribution import SimpleSALTDist
import os
import numpy as np
import pandas as pd
from lsst.sims.photUtils import BandpassDict
from lsst.sims.catUtils.supernovae import SNObject

__all__ = ['SimulationTile', 'EntireSimulation', 'TiledSimulation']

class EntireSimulation(Universe):
    """
    Simulation of a set of SN from a set of telescope pointings
    and a set of SN. The simulation is perfectly reproducible if
    both the pointings, paramsDF are the same (in terms of ordering)
    
    Parameters
    -----------
    rng : instance of `numpy.random.RandomState` 
    pointings: instance of `pd.DataFrame` 
    	dataFrame with a minimal set of columns
	[`expMJD`, `filter`, `fiveSigmaDepth`]
    paramsDF : `pd.DataFrame`
	the minimal set of columns are 
	[`snid`, `x0`, `t0`, `x1` , `c` , `snra`, `sndec`]

    Attributes
    ----------
    randomState : `numpy.random.RandomState`
    snParams : `pd.DataFrame`

    """
    def __init__(self, rng, pointings, paramsDF, angularUnits='degrees'):
        self.pointings = pointings
        self._paramsDf = paramsDF
        self._rng = rng
        self.angularUnits = angularUnits
        self.bandPasses = BandpassDict.loadTotalBandpassesFromFiles()
    
    @property
    def randomState(self):
        return self._rng

    @property
    def snParams(self):
        return self._paramsDf

    @staticmethod
    def getSNCosmoParamDict(odict, SNCosmoModel):
        mydict = dict()
        param_names = SNCosmoModel.param_names

        for param in odict.index.values:
            if param in param_names:
                mydict[param] = odict[param]
        return mydict
    
    def SN(self, snid, timeRange='model'):
        mySNParams = self.snParams.ix[snid]
        if self.angularUnits == 'radians':
            myra = np.degees(mySNParams.snra)
            mydec = np.degrees(mySNParams.sndec)
        elif self.angularUnits == 'degrees':
            myra = mySNParams.snra
            mydec = mySNParams.sndec
        sn = SNObject(ra=myra, dec=mydec)
        sncosmo_params = self.getSNCosmoParamDict(mySNParams, sn)
        sn.set(**sncosmo_params)
        return sn
    
    def lc(self, snid):
        sn = self.SN(snid, timeRange='model')
        lcMinTime = sn.mintime()
        lcMaxTime = sn.maxtime()
        # lcMinTime = self.SN(snid, timeRange='model').mintime()
        # lcMaxTime = self.SN(snid, timeRange='model').maxtime()
        if lcMinTime is None or lcMaxTime is None:
            df = self.pointings.copy()
        else:
            df = self.pointings.query('expMJD < @lcMaxTime and expMJD > @lcMinTime').copy()
        fluxerr = np.zeros(len(df))
        modelFlux = np.zeros(len(df))
        for i, rowtuple in enumerate(df.iterrows()):
            row = rowtuple[1]
            # print(row['expMJD'], row['filter'], row['fiveSigmaDepth'])
            bp = self.bandPasses[row['filter']]
            modelFlux[i] = self.staticModelFlux(sn, row['expMJD'],
                                                bandpassobject=bp)
            fluxerr[i] = sn.catsimBandFluxError(time=row['expMJD'],
                                                bandpassobject=bp,
                                                fluxinMaggies=modelFlux[i],
                                                m5=row['fiveSigmaDepth'])

        rng = self.randomState
        df['fluxerr'] = fluxerr
        deviations = rng.normal(size=len(df))
        df['deviations'] = deviations
        df['zp'] = 0.
        df['ModelFlux'] = modelFlux
        df['snid'] = snid
        df['flux'] = df['ModelFlux'] + df['deviations'] * df['fluxerr']
        df['zpsys']= 'ab'
        lc = df[['snid', 'expMJD', 'filter', 'ModelFlux', 'flux', 'fluxerr',
                 'zp', 'zpsys', 'fieldID']]
        return LightCurve(lc)
    
    @staticmethod
    def staticModelFlux(sn, time, bandpassobject):
          return sn.catsimBandFlux(bandpassobject=bandpassobject,
                                   time=time)
    def modelFlux(self, snid, time, bandpassobject):
        # assert len(times) == len(bands)
        # flux = np.zeros(len(times))
	sn = self.SN(snid)
	return self.staticModelFlux(sn, time=time, bandpassobject=bandpassobject)
        # return self.SN(snid).catsimBandFlux(bandpassobject=bandpassobject,
        #                                    time=time)


    def writeSNParams(self, paramFileName, IDVal=0):
	"""
	Write the dataframe `self.snParams` to a file 
<commit_msg>Added maxObsHistID as parameter to EntireSimulation -  self.maxObsHistID is set to this parameter, dafaulting to `None` - if the dataframe does not the column obsHistID, and this value is not   `None`, then raise a value Error<commit_after>#!/usr/bin/env python
from __future__ import absolute_import, print_function, division
from future.utils import with_metaclass
import abc

from opsimsummary import Tiling, HealpixTiles
from analyzeSN import LightCurve
from .universe import Universe
from .paramDistribution import SimpleSALTDist
import os
import numpy as np
import pandas as pd
from lsst.sims.photUtils import BandpassDict
from lsst.sims.catUtils.supernovae import SNObject

__all__ = ['SimulationTile', 'EntireSimulation', 'TiledSimulation']

class EntireSimulation(Universe):
    """
    Simulation of a set of SN from a set of telescope pointings
    and a set of SN. The simulation is perfectly reproducible if
    both the pointings, paramsDF are the same (in terms of ordering)
    
    Parameters
    -----------
    rng : instance of `numpy.random.RandomState` 
    pointings: instance of `pd.DataFrame` 
    	dataFrame with a minimal set of columns
	[`expMJD`, `filter`, `fiveSigmaDepth`]
    paramsDF : `pd.DataFrame`
	the minimal set of columns are 
	[`snid`, `x0`, `t0`, `x1` , `c` , `snra`, `sndec`]

    Attributes
    ----------
    randomState : `numpy.random.RandomState`
    snParams : `pd.DataFrame`

    """
    def __init__(self, rng, pointings, paramsDF, angularUnits='degrees',
                 maxObsHistID=None):
        self.pointings = pointings
        self._paramsDf = paramsDF
        self._rng = rng
        self.angularUnits = angularUnits
        self.bandPasses = BandpassDict.loadTotalBandpassesFromFiles()
        self.maxObsHistID = maxObsHistID
    
    @property
    def randomState(self):
        return self._rng

    @property
    def snParams(self):
        return self._paramsDf

    @staticmethod
    def getSNCosmoParamDict(odict, SNCosmoModel):
        mydict = dict()
        param_names = SNCosmoModel.param_names

        for param in odict.index.values:
            if param in param_names:
                mydict[param] = odict[param]
        return mydict
    
    def SN(self, snid, timeRange='model'):
        mySNParams = self.snParams.ix[snid]
        if self.angularUnits == 'radians':
            myra = np.degees(mySNParams.snra)
            mydec = np.degrees(mySNParams.sndec)
        elif self.angularUnits == 'degrees':
            myra = mySNParams.snra
            mydec = mySNParams.sndec
        sn = SNObject(ra=myra, dec=mydec)
        sncosmo_params = self.getSNCosmoParamDict(mySNParams, sn)
        sn.set(**sncosmo_params)
        return sn
    
    def lc(self, snid, maxObsHistID=None):
        if maxObsHistID is None:
            maxObsHistID = self.maxObsHistID
        sn = self.SN(snid, timeRange='model')
        lcMinTime = sn.mintime()
        lcMaxTime = sn.maxtime()
        # lcMinTime = self.SN(snid, timeRange='model').mintime()
        # lcMaxTime = self.SN(snid, timeRange='model').maxtime()
        if lcMinTime is None or lcMaxTime is None:
            df = self.pointings.copy()
        else:
            df = self.pointings.query('expMJD < @lcMaxTime and expMJD > @lcMinTime').copy().reset_index()
            if maxObsHistID is not None and ('obsHistID' in df.columns):
                raise ValueError('Cannot index if obsHistID column not provided')
        fluxerr = np.zeros(len(df))
        modelFlux = np.zeros(len(df))
        for i, rowtuple in enumerate(df.iterrows()):
            row = rowtuple[1]
            # print(row['expMJD'], row['filter'], row['fiveSigmaDepth'])
            bp = self.bandPasses[row['filter']]
            modelFlux[i] = self.staticModelFlux(sn, row['expMJD'],
                                                bandpassobject=bp)
            fluxerr[i] = sn.catsimBandFluxError(time=row['expMJD'],
                                                bandpassobject=bp,
                                                fluxinMaggies=modelFlux[i],
                                                m5=row['fiveSigmaDepth'])

        rng = self.randomState
        df['fluxerr'] = fluxerr
        deviations = rng.normal(size=len(df))
        df['deviations'] = deviations
        df['zp'] = 0.
        df['ModelFlux'] = modelFlux
        df['snid'] = snid
        df['flux'] = df['ModelFlux'] + df['deviations'] * df['fluxerr']
        df['zpsys']= 'ab'

        lc = df[['snid', 'expMJD', 'filter', 'ModelFlux', 'flux', 'fluxerr',
                 'zp', 'zpsys', 'fieldID']]
        return LightCurve(lc)
    
    @staticmethod
    def staticModelFlux(sn, time, bandpassobject):
          return sn.catsimBandFlux(bandpassobject=bandpassobject,
                                   time=time)
    def modelFlux(self, snid, time, bandpassobject):
        # assert len(times) == len(bands)
        # flux = np.zeros(len(times))
	sn = self.SN(snid)
	return self.staticModelFlux(sn, time=time, bandpassobject=bandpassobject)
        # return self.SN(snid).catsimBandFlux(bandpassobject=bandpassobject,
        #                                    time=time)


    def writeSNParams(self, paramFileName, IDVal=0):
	"""
	Write the dataframe `self.snParams` to a file 

{'fraction_non_alphanumeric': 0.10959177562631, 'fraction_numerical': 0.0013973450444156104, 'mean_word_length': 2.308022449653351, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3999181', 'n_tokens_mistral': 3169, 'n_tokens_neox': 3064, 'n_words': 722}