<commit_before>package dbnp.studycapturing

import org.nmcdsp.plugins.aaaa.SecUser

/**
 * Domain class describing the basic entity in the study capture part: the Study class.
 *
 * Revision information:
 * $Rev$
 * $Author$
 * $Date$
 */
class Study extends TemplateEntity {
	static searchable = {
    	[only: ['title', 'Description']] // the description field will be searched only if defined in a study template
    }

	SecUser owner   // The owner of the study. A new study is automatically owned by its creator.
	String title        // The title of the study
	String code 		// currently used as the external study ID, e.g. to reference a study in a SAM module
	Date dateCreated
	Date lastUpdated
	Date startDate
        List subjects
	List events
	List samplingEvents
	List eventGroups
	List samples
	List assays
	boolean published = false // Determines whether a study is private (only accessable by the owner and writers) or published (also visible to readers)

	static hasMany = [		
		subjects: Subject,
		samplingEvents: SamplingEvent,
		events: Event,
		eventGroups: EventGroup,
		samples: Sample,
		assays: Assay,
		persons: StudyPerson,
		publications: Publication
	]

	static constraints = {
		owner(nullable: true, blank: true)
		code(nullable:false, blank:true,unique:true)

		// TODO: add custom validator for 'published' to assess whether the study meets all quality criteria for publication
		// tested by SampleTests.testStudyPublish
	}

	static mapping = {
		autoTimestamp true

		// Workaround for bug http://jira.codehaus.org/browse/GRAILS-6754
		templateTextFields type: 'text'
                owner column:"studyowner"
                title column:"studytitle"
                code column:"studycode"
                subjects column:"studysubjects"
                events column:"studyevents"
                samplingEvents column:"studysamplingevents"
                eventGroups column:"studyeventgroups"
                samples column:"studysamples"
                assays column:"studyassays"

	}

	// The external identifier (studyToken) is currently the code of the study.
	// It is used from within dbNP submodules to refer to particular study in this GSCF instance.
	def getToken() { code }

	/**
	 * return the domain fields for this domain class
	 * @return List
	 */
	static List<TemplateField> giveDomainFields() { return Study.domainFields }

	static final List<TemplateField> domainFields = [
		new TemplateField(
			name: 'title',
			type: TemplateFieldType.STRING,
			required: true),
		new TemplateField(
			name: 'code',
			type: TemplateFieldType.STRING,
			preferredIdentifier:true,
			comment: 'Fill out the code by which many people will recognize your study',
			required: true),
		new TemplateField(
			name: 'startDate',
			type: TemplateFieldType.DATE,
			comment: 'Fill out the official start date or date of first action',
			required: true),
		new TemplateField(
			name: 'published',
			type: TemplateFieldType.BOOLEAN,
			comment: 'Determines whether this study is published (accessible for the study readers and, if the study is public, for anonymous users). A study can only be published if it meets certain quality criteria, which will be checked upon save.',
			required: true)
	]

	/**
	 * return the title of this study
	 */
	def String toString() {
		return title
	}

	/**
	 * returns all events and sampling events that do not belong to a group
	 */
	def Set<Event> getOrphanEvents() {
		def orphans =	events.findAll { event -> !event.belongsToGroup(eventGroups) } +
						samplingEvents.findAll { event -> !event.belongsToGroup(eventGroups) }

		return orphans
	}

	/**
	 * Return the unique Subject templates that are used in this study
	 */
	def Set<Template> giveSubjectTemplates() {
		TemplateEntity.giveTemplates(subjects)
	}

	/**
	 * Return all subjects for a specific template
	 * @param Template
	 * @return ArrayList<commit_msg>- removed the 'required' keyword from the Study's domainFields for the 'published' domainField as a 'required' arrow in the wizard did not make a lot of sense for a checkbox when that checkbox could be either 0 or 1<commit_after>package dbnp.studycapturing

import org.nmcdsp.plugins.aaaa.SecUser

/**
 * Domain class describing the basic entity in the study capture part: the Study class.
 *
 * Revision information:
 * $Rev$
 * $Author$
 * $Date$
 */
class Study extends TemplateEntity {
	static searchable = {
    	[only: ['title', 'Description']] // the description field will be searched only if defined in a study template
    }

	SecUser owner		// The owner of the study. A new study is automatically owned by its creator.
	String title        // The title of the study
	String code 		// currently used as the external study ID, e.g. to reference a study in a SAM module
	Date dateCreated
	Date lastUpdated
	Date startDate
	List subjects
	List events
	List samplingEvents
	List eventGroups
	List samples
	List assays
	boolean published = false // Determines whether a study is private (only accessable by the owner and writers) or published (also visible to readers)

	static hasMany = [		
		subjects: Subject,
		samplingEvents: SamplingEvent,
		events: Event,
		eventGroups: EventGroup,
		samples: Sample,
		assays: Assay,
		persons: StudyPerson,
		publications: Publication
	]

	static constraints = {
		owner(nullable: true, blank: true)
		code(nullable:false, blank:true,unique:true)

		// TODO: add custom validator for 'published' to assess whether the study meets all quality criteria for publication
		// tested by SampleTests.testStudyPublish
	}

	static mapping = {
		autoTimestamp true

		// Workaround for bug http://jira.codehaus.org/browse/GRAILS-6754
		templateTextFields type: 'text'
		owner column: "studyowner"
		title column: "studytitle"
		code column: "studycode"
		subjects column: "studysubjects"
		events column: "studyevents"
		samplingEvents column: "studysamplingevents"
		eventGroups column: "studyeventgroups"
		samples column: "studysamples"
		assays column: "studyassays"
	}

	// The external identifier (studyToken) is currently the code of the study.
	// It is used from within dbNP submodules to refer to particular study in this GSCF instance.
	def getToken() { code }

	/**
	 * return the domain fields for this domain class
	 * @return List
	 */
	static List<TemplateField> giveDomainFields() { return Study.domainFields }

	static final List<TemplateField> domainFields = [
		new TemplateField(
			name: 'title',
			type: TemplateFieldType.STRING,
			required: true),
		new TemplateField(
			name: 'code',
			type: TemplateFieldType.STRING,
			preferredIdentifier:true,
			comment: 'Fill out the code by which many people will recognize your study',
			required: true),
		new TemplateField(
			name: 'startDate',
			type: TemplateFieldType.DATE,
			comment: 'Fill out the official start date or date of first action',
			required: true),
		new TemplateField(
			name: 'published',
			type: TemplateFieldType.BOOLEAN,
			comment: 'Determines whether this study is published (accessible for the study readers and, if the study is public, for anonymous users). A study can only be published if it meets certain quality criteria, which will be checked upon save.',
			required: false)
	]

	/**
	 * return the title of this study
	 */
	def String toString() {
		return title
	}

	/**
	 * returns all events and sampling events that do not belong to a group
	 */
	def Set<Event> getOrphanEvents() {
		def orphans =	events.findAll { event -> !event.belongsToGroup(eventGroups) } +
						samplingEvents.findAll { event -> !event.belongsToGroup(eventGroups) }

		return orphans
	}

	/**
	 * Return the unique Subject templates that are used in this study
	 */
	def Set<Template> giveSubjectTemplates() {
		TemplateEntity.giveTemplates(subjects)
	}

	/**
	 * Return all subjects for a specific template
	 * @param Template
	 * @return ArrayList
{'fraction_non_alphanumeric': 0.07892399441695216, 'fraction_numerical': 0.0012688745083111281, 'mean_word_length': 3.587892898719441, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2362075', 'n_tokens_mistral': 2377, 'n_tokens_neox': 2138, 'n_words': 866}