def test_min_wrong_type_fails(self):
     mock_ui_holder = MockUIHolder()
     light_cone_form = make_form(self.default_form_values,LightConeForm,{},prefix='light_cone')
     mock_ui_holder.update(light_cone = light_cone_form)
     for filter_obj, val in [(self.filter, '3.0'), (self.filter_float, 'a'), (self.filter_long, '3.0')]:
         record_filter_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(filter_obj.id),'min': val}, prefix='record_filter',ui_holder=mock_ui_holder)
         self.assertFalse(record_filter_form.is_valid())
    def test_min_or_max_required_for_other_filter(self):
        mock_ui_holder = MockUIHolder()
        light_cone_form = make_form(self.default_form_values,LightConeForm,{},prefix='light_cone')
        mock_ui_holder.update(light_cone = light_cone_form)
        record_filter_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(self.filter_long.id)}, prefix='record_filter',ui_holder=mock_ui_holder)

        self.assertFalse(record_filter_form.is_valid())
    def test_min_less_than_max_passes(self):
        mock_ui_holder = MockUIHolder()
        light_cone_form = make_form(self.default_form_values,LightConeForm,{},prefix='light_cone')
        mock_ui_holder.update(light_cone = light_cone_form)
        record_filter_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(self.filter.id),'max': '30', 'min': '3'}, prefix='record_filter',ui_holder=mock_ui_holder)

        self.assertTrue(record_filter_form.is_valid())
    def test_min_and_max_not_used_for_no_filter(self):
        from tao.forms import NO_FILTER
        mock_ui_holder = MockUIHolder()
        light_cone_form = make_form(self.default_form_values, LightConeForm, {}, prefix='light_cone')
        mock_ui_holder.update(light_cone = light_cone_form)
        record_filter_form = make_form(self.default_form_values, RecordFilterForm, {'filter': 'X-'+NO_FILTER}, prefix='record_filter', ui_holder=mock_ui_holder)

        self.assertTrue(record_filter_form.is_valid())
    def test_min_greater_than_max_fails(self):
        mock_ui_holder = MockUIHolder()
        light_cone_form = make_form(self.default_form_values,LightConeForm,{},prefix='light_cone')
        mock_ui_holder.update(light_cone = light_cone_form)

        record_filter_form = make_form(self.default_form_values,RecordFilterForm,{'max': '3', 'min': '9'}, prefix='record_filter',ui_holder=mock_ui_holder)

        self.assertFalse(record_filter_form.is_valid())
        self.assertEqual(['The "min" field must be less than the "max" field.'], record_filter_form.errors['min'])
    def test_min_or_max_required_when_no_default(self):
        data_set_no_default = DataSetFactory.create(simulation=self.simulation, galaxy_model=GalaxyModelFactory.create())
        new_filter = DataSetPropertyFactory.create(dataset=data_set_no_default)
        mock_ui_holder = MockUIHolder()
        light_cone_form = make_form(self.default_form_values,LightConeForm,{'galaxy_model': data_set_no_default.id, 'output_properties': [str(new_filter.id)],},prefix='light_cone')
        mock_ui_holder.update(light_cone = light_cone_form)
        record_filter_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(new_filter.id)}, prefix='record_filter',ui_holder=mock_ui_holder)

        self.assertFalse(record_filter_form.is_valid())
    def test_max_or_min_empty_passes(self):
        mock_ui_holder = MockUIHolder()
        lc_form = make_form(self.default_form_values,LightConeForm,{},prefix='light_cone')
        mock_ui_holder.update(light_cone = lc_form)

        rf_form_no_min = make_form(self.default_form_values,RecordFilterForm,{'max': '3', 'min': ''}, prefix='record_filter',ui_holder=mock_ui_holder)
        rf_form_no_max = make_form(self.default_form_values,RecordFilterForm,{'max': '', 'min': '9'}, prefix='record_filter',ui_holder=mock_ui_holder)

        self.assertTrue(rf_form_no_min.is_valid())
        self.assertTrue(rf_form_no_max.is_valid())
 def test_min_or_max_provided_is_valid(self):
     mock_ui_holder = MockUIHolder()
     light_cone_form = make_form(self.default_form_values,LightConeForm,{},prefix='light_cone')
     mock_ui_holder.update(light_cone = light_cone_form)
     # test on default
     record_filter_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(self.filter.id),'min':'10'}, prefix='record_filter',ui_holder=mock_ui_holder)
     self.assertTrue(record_filter_form.is_valid())
     # test on other
     record_filter_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(self.filter_long.id),'min':'10'}, prefix='record_filter',ui_holder=mock_ui_holder)
     self.assertTrue(record_filter_form.is_valid())
    def test_max_min_length(self):
        mock_ui_holder = MockUIHolder()
        lc_form = make_form(self.default_form_values,LightConeForm,{},prefix='light_cone')
        mock_ui_holder.update(light_cone = lc_form)
        max_overflow_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(self.filter.id), 'max': '100000000000000000000', 'min': '7'}, prefix='record_filter',ui_holder=mock_ui_holder)
        self.assertFalse(max_overflow_form.is_valid())
        self.assertEqual(['Ensure that there are no more than 20 digits in total.'], max_overflow_form.errors['max'])

        min_overflow_form = make_form(self.default_form_values,RecordFilterForm,{'filter':'D-'+str(self.filter.id), 'max': '2', 'min': '1.000000000000000000001'}, prefix='record_filter',ui_holder=mock_ui_holder)
        self.assertFalse(min_overflow_form.is_valid())
        self.assertEqual(['Ensure that there are no more than 20 digits in total.'], min_overflow_form.errors['min'])
    def test_light_cone_geometry(self):
        xml_parameters = {
            'catalogue_geometry': 'light-cone',
            'dark_matter_simulation': self.simulation.id,
            'galaxy_model': self.galaxy_model.id,
            'redshift_min': 0.2,
            'redshift_max': 0.3,
            'ra_opening_angle': 71.565,
            'dec_opening_angle': 41.811,
            'output_properties': [self.filter.id, self.output_prop.id],
            'light_cone_type': 'unique',
            'number_of_light_cones': 1,
            }
        xml_parameters.update({
            'username' : 'test', # self.user.username,
            'dark_matter_simulation': self.simulation.name,
            'galaxy_model': self.galaxy_model.name,
            'output_properties_1_name' : self.filter.name,
            'output_properties_1_label' : self.filter.label,
            'output_properties_1_units' : self.filter.units,
            'output_properties_1_description' : self.filter.description,
            'output_properties_2_name' : self.output_prop.name,
            'output_properties_2_label' : self.output_prop.label,
            'output_properties_2_description' : self.filter.description,
            'output_properties_3_name' : self.computed_filter.name,
            'output_properties_3_label' : self.computed_filter.label,
            'output_properties_3_description' : self.computed_filter.description,
        })
        xml_parameters.update({
            'filter': self.filter.name,
            'filter_min' : '1000000',
            'filter_max' : 'None',
            })
        xml_parameters.update({
            'ssp_encoding': self.stellar_model.encoding,
            'band_pass_filter_label': self.band_pass_filter.label,
            'band_pass_filter_id': self.band_pass_filter.filter_id,
            'band_pass_filter_name': self.band_pass_filter.filter_id,
            'dust_model_name': self.dust_model.name,
            })
        xml_parameters.update({
            'light_cone_id': FormsGraph.LIGHT_CONE_ID,
            'csv_dump_id': FormsGraph.OUTPUT_ID,
            'bandpass_filter_id': FormsGraph.BANDPASS_FILTER_ID,
            'sed_id': FormsGraph.SED_ID,
            'dust_id': FormsGraph.DUST_ID,
        })
        xml_str = light_cone_xml(xml_parameters)
        mock_ui_holder = MockUIHolder()
        mock_ui_holder.dataset = self.dataset
        form = make_form_xml(LightConeForm, xml_str, prefix='light_cone', ui_holder=mock_ui_holder)

        self.assertEquals(LightConeForm.CONE, form.data['light_cone-catalogue_geometry'])
        self.assertEquals(self.dataset.id, form.data['light_cone-galaxy_model'])
        self.assertEquals(self.simulation.id, form.data['light_cone-dark_matter_simulation'])
        self.assertEquals('unique', form.data['light_cone-light_cone_type'])
        self.assertEquals('1', form.data['light_cone-number_of_light_cones'])
        self.assertEquals('0.2', form.data['light_cone-redshift_min'])
        self.assertEquals('0.3', form.data['light_cone-redshift_max'])
        self.assertEquals('71.565', form.data['light_cone-ra_opening_angle'])
        self.assertEquals('71.565', form.data['light_cone-ra_opening_angle'])
        self.assertEquals('41.811', form.data['light_cone-dec_opening_angle'])
        op_list = form.data['light_cone-output_properties']
        self.assertEquals(3, len(op_list))
        self.assertTrue(self.filter.id in op_list)
        self.assertTrue(self.output_prop.id in op_list)
            })
        xml_parameters.update({
            'ssp_encoding': self.stellar_model.encoding,
            'band_pass_filter_label': 'BPFN', # self.band_pass_filter.label,
            'band_pass_filter_id': 1L, # self.band_pass_filter.filter_id,
            'band_pass_filter_name': 'BPFN',
            'dust_model_name': 'DM', # self.dust_model.name,
        })
        xml_parameters.update({
            'light_cone_id': FormsGraph.LIGHT_CONE_ID,
            'csv_dump_id': FormsGraph.OUTPUT_ID,
            'bandpass_filter_id': FormsGraph.BANDPASS_FILTER_ID,
            'sed_id': FormsGraph.SED_ID,
            'dust_id': FormsGraph.DUST_ID,
        })
        mock_ui_holder = MockUIHolder()
        xml_str = light_cone_xml(xml_parameters)
        light_cone_form = make_form({}, LightConeForm, {'dark_matter_simulation':self.simulation.id, 'galaxy_model':self.dataset.id, 'catalogue_geometry': 'light-cone'}, prefix='light_cone')
        mock_ui_holder.update(light_cone = light_cone_form)
        mock_ui_holder.dataset = self.dataset
        rf_form = make_form_xml(RecordFilterForm, xml_str, prefix='record_filter', ui_holder=mock_ui_holder)

        self.assertEquals('D-' + str(self.filter.id), rf_form.data['record_filter-filter'])
        self.assertEquals('1000000', rf_form.data['record_filter-min'])
        self.assertEquals(None, rf_form.data['record_filter-max'])

    def test_sed_form(self):
        xml_parameters = {
            'catalogue_geometry': 'light-cone',
            'dark_matter_simulation': self.simulation.id, # self.simulation.id,
            'galaxy_model': self.galaxy_model.id, #self.galaxy_model.id,
    def test_unique_cone(self):
        form_parameters = {
            'catalogue_geometry': 'light-cone',
            'dark_matter_simulation': self.simulation.id,
            'galaxy_model': self.galaxy_model.id,
            'redshift_min': 0.0,
            'redshift_max': 0.2,
            'ra_opening_angle': 12.001,
            'dec_opening_angle': 10.003,
            'output_properties' : [self.filter.id, self.output_prop.id, self.computed_filter.id],
            'light_cone_type': 'unique',
            'number_of_light_cones': 8,
            }
        xml_parameters = form_parameters.copy()
        xml_parameters.update({
            'username' : self.user.username,
            'dark_matter_simulation': self.simulation.name,
            'galaxy_model': self.galaxy_model.name,
            'output_properties_1_name' : self.filter.name,
            'output_properties_1_label' : self.filter.label,
            'output_properties_1_units' : self.filter.units,
            'output_properties_1_description' : self.filter.description,
            'output_properties_2_name' : self.output_prop.name,
            'output_properties_2_label' : self.output_prop.label,
            'output_properties_2_description' : self.output_prop.description,
            'output_properties_3_name' : self.computed_filter.name,
            'output_properties_3_label' : self.computed_filter.label,
            'output_properties_3_description' : self.computed_filter.description,
            })
        xml_parameters.update({
            'filter': self.filter.name,
            'filter_min' : '1000000',
            'filter_max' : 'None',
        })
        xml_parameters.update({
            'apply_sed': False,
        })
        xml_parameters.update({
            'ssp_encoding': self.stellar_model.encoding,
            'band_pass_filter_label': self.band_pass_filter.label,
            'band_pass_filter_id': self.band_pass_filter.filter_id,
            'band_pass_filter_name': self.band_pass_filter.filter_id,
            'dust_model_name': self.dust_model.name,
        })
        xml_parameters.update({
            'light_cone_id': FormsGraph.LIGHT_CONE_ID,
            'csv_dump_id': FormsGraph.OUTPUT_ID,
            'bandpass_filter_id': FormsGraph.BANDPASS_FILTER_ID,
            'sed_id': FormsGraph.SED_ID,
            'dust_id': FormsGraph.DUST_ID,
        })
        # TODO: there are commented out elements which are not implemented yet
        # comments are ignored by assertXmlEqual

        expected_parameter_xml = light_cone_xml(xml_parameters)

        mock_ui_holder = MockUIHolder()
        light_cone_form = make_form({}, LightConeForm, form_parameters, ui_holder=mock_ui_holder, prefix='light_cone')
        sed_form = make_form({}, SEDForm, self.sed_parameters, ui_holder=mock_ui_holder, prefix='sed')
        output_form = make_form({}, OutputFormatForm, {'supported_formats': 'csv'}, ui_holder=mock_ui_holder,
                                    prefix='output_format')
        mock_ui_holder.update(light_cone = light_cone_form, sed = sed_form, output_format = output_form)
        record_filter_form = make_form({}, RecordFilterForm, {'filter':'D-'+str(self.filter.id),'min':str(1000000)},
                                           ui_holder=mock_ui_holder, prefix='record_filter')
        self.assertEqual({}, light_cone_form.errors)
        self.assertEqual({}, sed_form.errors)
        self.assertEqual({}, record_filter_form.errors)
        self.assertEqual({}, output_form.errors)

        mock_ui_holder.update(record_filter = record_filter_form)
        mock_ui_holder.dataset = self.dataset
        job = workflow.save(self.user, mock_ui_holder)
        actual_parameter_xml = job.parameters

        self.assertEqual(self.dataset.database, job.database)
        self.assertXmlEqual(expected_parameter_xml, actual_parameter_xml)
    def test_no_dust(self):
        form_parameters = {
            'catalogue_geometry': 'box',
            'dark_matter_simulation': self.simulation.id,
            'galaxy_model': self.dataset.id,
            'output_properties' : [self.filter.id],
            'snapshot': self.snapshot.id,
            'box_size': 20,
            'rng_seed': 12345678901234567890
            }
        xml_parameters = form_parameters.copy()
        xml_parameters.update({
            'username' : self.user.username,
            'dark_matter_simulation': self.simulation.name,
            'galaxy_model': self.galaxy_model.name,
            'output_properties_1_name' : self.filter.name,
            'output_properties_1_label' : self.filter.label,
            'output_properties_1_units' : self.filter.units,
            'output_properties_1_description' : self.filter.description,
            'redshift' : float(self.snapshot.redshift),
            })
        xml_parameters.update({
            'filter': self.filter.name,
            'filter_min' : 'None',
            'filter_max' : '1000000',
            })
        # TODO: there are commented out elements which are not implemented yet
        xml_parameters.update({
            'ssp_encoding': self.stellar_model.encoding,
            'band_pass_filter_label': self.band_pass_filter.label,
            'band_pass_filter_id': self.band_pass_filter.filter_id,
            'band_pass_filter_name': self.band_pass_filter.filter_id,
            'band_pass_filter_description': self.band_pass_filter.description,
            'band_pass_extension': 'absolute',
            })
        xml_parameters.update({
            'light_cone_id': FormsGraph.LIGHT_CONE_ID,
            'csv_dump_id': FormsGraph.OUTPUT_ID,
            'bandpass_filter_id': FormsGraph.BANDPASS_FILTER_ID,
            'sed_id': FormsGraph.SED_ID,
            'dust_id': FormsGraph.DUST_ID,
            })
        # comments are ignored by assertXmlEqual
        expected_parameter_xml = stripped_joined_lines("""<?xml version="1.0"?>
            <!-- Using the XML namespace provides a version for future modifiability.  The timestamp allows
                 a researcher to know when this parameter file was generated.  -->
            <tao xmlns="http://tao.asvo.org.au/schema/module-parameters-v1" timestamp="2012-12-20T13:55:36+10:00">

                <!-- Username submitting the job -->
                <username>%(username)s</username>

                <!-- Workflow name identifies which workflow is to be executed.
                     This is currently a placeholder, the name is ignored. -->
                <workflow name="alpha-light-cone-image">

                    <!-- Global Configuration Parameters -->
                    <schema-version>2.0</schema-version>

                    <!-- Light-cone module parameters -->
                    <light-cone id="%(light_cone_id)s">
                        <!-- Module Version Number -->
                        <module-version>1</module-version>

                        <!-- Is the query a light-cone or box? -->
                        <geometry>box</geometry>

                        <!-- Selected Simuation -->
                        <simulation>%(dark_matter_simulation)s</simulation>

                        <!-- Selected Galaxy Model -->
                        <galaxy-model>%(galaxy_model)s</galaxy-model>

                        <!-- The number of light-cones to generate
                        <box-repetition>unique | random</box-repetition>
                        <num-cones>1</num-cones> -->

                        <!-- The min and max redshifts to filter by -->
                        <redshift>%(redshift).10f</redshift>

                        <!-- Size of box to return -->
                        <query-box-size units="Mpc">%(box_size)d</query-box-size>

                        <!-- RNG Seed -->
                        <!-- This will be added by the workflow after the job has been completed
                             to enable the job to be repeated.
                             The information stored may change, the intent is to store whatever is
                             required to re-run the job and obtain the same results.-->
                        <rng-seed>12345678901234567890</rng-seed> 

                        <!-- List of fields to be included in the output file -->
                        <output-fields>
                            <item description="%(output_properties_1_description)s" label="%(output_properties_1_label)s" units="%(output_properties_1_units)s">%(output_properties_1_name)s</item>
                        </output-fields>

                    </light-cone>

                    <!-- File output module -->
                    <csv id="%(csv_dump_id)s">
                        <fields>
                            <item label="%(output_properties_1_label)s" units="%(output_properties_1_units)s">%(output_properties_1_name)s</item>
                            <item label="bandpass (Absolute)">%(band_pass_filter_name)s_absolute</item>
                            <!-- <item label="bandpass (Apparent)">%(band_pass_filter_name)s_apparent</item> -->
                        </fields>

                        <!-- Module Version Number -->
                        <module-version>1</module-version>

                        <!-- Output file format -->
                        <filename>tao.output.csv</filename>

                        <parents>
                            <item>%(bandpass_filter_id)s</item>
                        </parents>

                    </csv>

                    <!-- Optional: Spectral Energy Distribution parameters -->
                    <sed id="%(sed_id)s">
                        <!-- Module Version Number -->
                        <module-version>1</module-version>

                        <parents>
                            <item>%(light_cone_id)s</item>
                        </parents>

                        %(ssp_encoding)s
                    </sed>

                    <filter id="%(bandpass_filter_id)s">
                        <module-version>1</module-version>
                        <parents>
                            <item>%(sed_id)s</item>
                        </parents>

                        <!-- Bandpass Filters) -->
                        <bandpass-filters>
                            <item description="%(band_pass_filter_description)s" label="%(band_pass_filter_label)s" selected="%(band_pass_extension)s">%(band_pass_filter_id)s</item>
                        </bandpass-filters>
                    </filter>

                    <!-- Record Filter -->
                    <record-filter>
                        <!-- Module Version Number -->
                        <module-version>1</module-version>

                        <!-- Note that the units are for readability,
                             no unit conversion is supported.  The consumer of the
                             parameter file should check that the expected units are provided. -->
                        <filter>
                            <filter-attribute>%(filter)s</filter-attribute>
                            <filter-min units="Msun/h">%(filter_min)s</filter-min>
                            <filter-max units="Msun/h">%(filter_max)s</filter-max>
                        </filter>
                    </record-filter>

                    <!-- Image generation module parameters
                    <image-generator>
                        <!- Module Version Number ->
                        <module-version>1</module-version>

                        <!- Image size parameters ->
                        <image-width units="px">1024</image-width>
                        <image-height units="px">1024</image-height>

                        <!- Focal scale parameters ->
                        <focalx units="??">1024</focalx>
                        <focaly units="??">1024</focaly>

                        <!- Image offset parameters ->
                        <image-offsetx units="??">512</image-offsetx>
                        <image-offsety units="??">0</image-offsety>
                    </image-generator> -->

                </workflow>

                <!-- The signature is automatically generated and is intended to be used when running
                     old versions of the science modules (to remove the need for the UI to parse and check
                     every version. -->
                <signature>base64encodedsignature</signature>

            </tao>
        """) % xml_parameters
        
        mock_ui_holder = MockUIHolder()
        light_cone_form = make_form({}, LightConeForm, form_parameters, ui_holder=mock_ui_holder, prefix='light_cone')
        sed_form = make_form({}, SEDForm, self.sed_parameters_no_dust, ui_holder=mock_ui_holder, prefix='sed')
        output_form = make_form({}, OutputFormatForm, {'supported_formats': 'csv'}, ui_holder=mock_ui_holder, prefix='output_format')
        mock_ui_holder.update(light_cone = light_cone_form, sed = sed_form, output_format = output_form)
        mock_ui_holder.dataset = self.dataset
        record_filter_form = make_form({}, RecordFilterForm, {'filter':'D-'+str(self.filter.id),'max':str(1000000)},
                                           ui_holder=mock_ui_holder, prefix='record_filter')
        self.assertEqual({}, light_cone_form.errors)
        self.assertEqual({}, sed_form.errors)
        self.assertEqual({}, record_filter_form.errors)
        self.assertEqual({}, output_form.errors)

        mock_ui_holder.update(record_filter = record_filter_form)
        job = workflow.save(self.user, mock_ui_holder)
        actual_parameter_xml = job.parameters

        self.assertXmlEqual(expected_parameter_xml, actual_parameter_xml)
        self.assertEqual(self.dataset.database, job.database)