1pub mod benchmarks;
41pub mod citations;
42pub mod collaboration;
43pub mod conferences;
44pub mod datasets;
45pub mod experiments;
46pub mod funding;
47pub mod peer_review;
48pub mod publications;
49pub mod reproducibility;
50
51pub use benchmarks::*;
53pub use collaboration::*;
54pub use datasets::*;
55pub use funding::*;
56
57pub use experiments::{
59 CpuInfo, DataType, DatasetInfo, DatasetStatistics, EarlyStoppingConfig, Experiment,
60 ExperimentConfig, ExperimentMetadata, ExperimentNote, ExperimentResult, ExperimentRunner,
61 ExperimentStatus, ExperimentTimeline, GpuInfo, HardwareConfig as ExperimentHardwareConfig,
62 MemoryAllocationStrategy, MemoryConfig, NoteType, OptimizationMode, ParallelConfig,
63 PreprocessingStep, ReproducibilityChecklist, ReproducibilityInfo, ResourceMonitor,
64 ResourceUsage, RunStatus, SystemInfo as ExperimentSystemInfo, TrainingHistory,
65};
66
67pub use reproducibility::{
69 CpuSpec, Dependency, Difference, DifferenceCategory, EnvironmentSnapshot, GpuSpec,
70 HardwareConfig as ReproducibilityHardwareConfig, IssueSeverity, IssueType, MemorySpec,
71 ReproducibilityChecklist as ReproducibilityChecklistType, ReproducibilityConfig,
72 ReproducibilityIssue, ReproducibilityManager, ReproducibilityReport, ReproducibilityStorage,
73 SimilarityMetrics, StorageSpec, SystemInfo as ReproducibilitySystemInfo, VerificationResult,
74 VerificationStatus,
75};
76
77pub use citations::{
80 Author as CitationAuthor, BibliographyFormat, Citation, CitationManager,
81 CitationStyle as CitationStyleType, DateFormat, FormattingRules, InTextFormat, NameFormat,
82 PublicationType as CitationPublicationType, PunctuationRules, SortDirection, SortField,
83 SortingRules, TitleFormat,
84};
85
86pub use publications::{
88 Affiliation, Author as PublicationAuthor, AuthorPosition, BibTeXEntry, Bibliography,
89 CitationStyle as PublicationCitationStyle, Decision, Figure, FigureType, ManuscriptSection,
90 Publication, PublicationStatus, PublicationType as PublicationTypeEnum,
91 Review as PublicationReview, ReviewRecommendation as PublicationReviewRecommendation,
92 ReviewerInfo, SectionType, SubmissionRecord, SubmissionStatus, Table, Venue, VenueType,
93};
94
95pub use peer_review::{
97 MetaReview, PeerReview, PeerReviewSystem, ReviewAssignment, ReviewCriterion, ReviewDiscussion,
98 ReviewQualityAssessment, ReviewQualityMetric, ReviewRecommendation as PeerReviewRecommendation,
99 ReviewSession, ReviewSessionStatus, ReviewStatus, ReviewType, Reviewer, ReviewerAvailability,
100 ReviewerHistory, ReviewerPreferences, ReviewerQualityMetrics, WrittenReview,
101};
102
103pub use conferences::{
105 Conference, ConferenceDates, ConferenceManager, DeadlineType, Review as ConferenceReview,
106 ReviewFormat, ReviewProcess, ReviewRecommendation as ConferenceReviewRecommendation,
107 Submission, SubmissionStatus as ConferenceSubmissionStatus,
108};
109
110use crate::error::{OptimError, Result};
111use chrono::{DateTime, Utc};
112use serde::{Deserialize, Serialize};
113use std::collections::HashMap;
114use std::path::PathBuf;
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct ResearchProject {
119 pub name: String,
121 pub description: String,
123 pub research_area: ResearchArea,
125 pub status: ProjectStatus,
127 pub researchers: Vec<Researcher>,
129 pub funding: Option<FundingInfo>,
131 pub timeline: ProjectTimeline,
133 pub experiments: Vec<Experiment>,
135 pub publications: Vec<Publication>,
137 pub settings: ProjectSettings,
139 pub created_at: DateTime<Utc>,
141 pub modified_at: DateTime<Utc>,
143}
144
145#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
147pub enum ResearchArea {
148 MachineLearning,
150 DeepLearning,
152 OptimizationTheory,
154 ComputerVision,
156 NaturalLanguageProcessing,
158 ReinforcementLearning,
160 ScientificComputing,
162 HighPerformanceComputing,
164 DistributedSystems,
166 QuantumComputing,
168 Interdisciplinary,
170 Other(String),
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
176pub enum ProjectStatus {
177 Planning,
179 Active,
181 DataCollection,
183 Analysis,
185 Writing,
187 UnderReview,
189 Published,
191 Completed,
193 OnHold,
195 Cancelled,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct Researcher {
202 pub name: String,
204 pub email: String,
206 pub affiliation: String,
208 pub orcid: Option<String>,
210 pub role: ResearcherRole,
212 pub expertise: Vec<String>,
214 pub contact_info: ContactInfo,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
220pub enum ResearcherRole {
221 PrincipalInvestigator,
223 CoPrincipalInvestigator,
225 SeniorResearcher,
227 Postdoc,
229 PhDStudent,
231 MastersStudent,
233 UndergraduateStudent,
235 ResearchAssistant,
237 Collaborator,
239 Advisor,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize, Default)]
245pub struct ContactInfo {
246 pub phone: Option<String>,
248 pub office_address: Option<String>,
250 pub mailing_address: Option<String>,
252 pub website: Option<String>,
254 pub social_media: HashMap<String, String>,
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize)]
260pub struct FundingInfo {
261 pub agency: String,
263 pub grant_number: String,
265 pub grant_title: String,
267 pub amount: Option<f64>,
269 pub currency: String,
271 pub start_date: DateTime<Utc>,
273 pub end_date: DateTime<Utc>,
275 pub award_date: Option<DateTime<Utc>>,
277}
278
279#[derive(Debug, Clone, Serialize, Deserialize)]
281pub struct ProjectTimeline {
282 pub start_date: DateTime<Utc>,
284 pub planned_end_date: DateTime<Utc>,
286 pub actual_end_date: Option<DateTime<Utc>>,
288 pub milestones: Vec<Milestone>,
290 pub progress_updates: Vec<ProgressUpdate>,
292}
293
294#[derive(Debug, Clone, Serialize, Deserialize)]
296pub struct Milestone {
297 pub name: String,
299 pub description: String,
301 pub planned_date: DateTime<Utc>,
303 pub completed_date: Option<DateTime<Utc>>,
305 pub status: MilestoneStatus,
307 pub deliverables: Vec<String>,
309}
310
311#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
313pub enum MilestoneStatus {
314 NotStarted,
316 InProgress,
318 Completed,
320 Delayed,
322 Cancelled,
324}
325
326#[derive(Debug, Clone, Serialize, Deserialize)]
328pub struct ProgressUpdate {
329 pub timestamp: DateTime<Utc>,
331 pub author: String,
333 pub summary: String,
335 pub description: String,
337 pub completion_percentage: f64,
339 pub next_steps: Vec<String>,
341 pub challenges: Vec<String>,
343}
344
345#[derive(Debug, Clone, Serialize, Deserialize)]
347pub struct ProjectSettings {
348 pub enable_reproducibility: bool,
350 pub enable_backups: bool,
352 pub backup_frequency_hours: u32,
354 pub data_retention_days: u32,
356 pub privacy_settings: PrivacySettings,
358 pub collaboration_settings: CollaborationSettings,
360 pub publication_settings: PublicationSettings,
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct PrivacySettings {
367 pub visibility: ProjectVisibility,
369 pub data_sharing: DataSharingPolicy,
371 pub allow_anonymous_access: bool,
373 pub embargo_period_days: Option<u32>,
375}
376
377#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
379pub enum ProjectVisibility {
380 Public,
382 Internal,
384 Private,
386 Restricted,
388}
389
390#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
392pub enum DataSharingPolicy {
393 Open,
395 OnRequest,
397 Restricted,
399 NoSharing,
401}
402
403#[derive(Debug, Clone, Serialize, Deserialize)]
405pub struct CollaborationSettings {
406 pub enable_realtime_collaboration: bool,
408 pub enable_version_control: bool,
410 pub enable_peer_review: bool,
412 pub enable_discussions: bool,
414 pub max_collaborators: Option<u32>,
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize)]
420pub struct PublicationSettings {
421 pub default_format: PublicationFormat,
423 pub enable_auto_citations: bool,
425 pub citation_style: CitationStyle,
427 pub enable_preprints: bool,
429 pub target_venues: Vec<String>,
431}
432
433#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
435pub enum PublicationFormat {
436 LaTeX,
438 Markdown,
440 Html,
442 Pdf,
444 Word,
446 Notebook,
448}
449
450#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
452pub enum CitationStyle {
453 APA,
455 IEEE,
457 ACM,
459 Nature,
461 Science,
463 Custom(String),
465}
466
467#[derive(Debug)]
469pub struct ResearchProjectManager {
470 projects: HashMap<String, ResearchProject>,
472 storage_dir: PathBuf,
474 settings: ManagerSettings,
476}
477
478#[derive(Debug, Clone, Serialize, Deserialize)]
480pub struct ManagerSettings {
481 pub default_template: Option<String>,
483 pub auto_save_frequency: u32,
485 pub enable_cloud_backup: bool,
487 pub cloud_provider: Option<String>,
489 pub notifications: NotificationSettings,
491}
492
493#[derive(Debug, Clone, Serialize, Deserialize)]
495pub struct NotificationSettings {
496 pub email_enabled: bool,
498 pub slack_enabled: bool,
500 pub webhook_url: Option<String>,
502 pub frequency: NotificationFrequency,
504}
505
506#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
508pub enum NotificationFrequency {
509 Realtime,
511 Daily,
513 Weekly,
515 Monthly,
517 Important,
519 Disabled,
521}
522
523impl ResearchProject {
524 pub fn new(name: &str) -> Self {
526 let now = Utc::now();
527 Self {
528 name: name.to_string(),
529 description: String::new(),
530 research_area: ResearchArea::MachineLearning,
531 status: ProjectStatus::Planning,
532 researchers: Vec::new(),
533 funding: None,
534 timeline: ProjectTimeline {
535 start_date: now,
536 planned_end_date: now + chrono::Duration::days(365),
537 actual_end_date: None,
538 milestones: Vec::new(),
539 progress_updates: Vec::new(),
540 },
541 experiments: Vec::new(),
542 publications: Vec::new(),
543 settings: ProjectSettings::default(),
544 created_at: now,
545 modified_at: now,
546 }
547 }
548
549 pub fn description(mut self, description: &str) -> Self {
551 self.description = description.to_string();
552 self.modified_at = Utc::now();
553 self
554 }
555
556 pub fn research_area(mut self, area: ResearchArea) -> Self {
558 self.research_area = area;
559 self.modified_at = Utc::now();
560 self
561 }
562
563 pub fn add_researcher(mut self, name: &str, email: &str) -> Self {
565 let researcher = Researcher {
566 name: name.to_string(),
567 email: email.to_string(),
568 affiliation: String::new(),
569 orcid: None,
570 role: ResearcherRole::Collaborator,
571 expertise: Vec::new(),
572 contact_info: ContactInfo::default(),
573 };
574 self.researchers.push(researcher);
575 self.modified_at = Utc::now();
576 self
577 }
578
579 pub fn funding(mut self, funding: FundingInfo) -> Self {
581 self.funding = Some(funding);
582 self.modified_at = Utc::now();
583 self
584 }
585
586 pub fn enable_reproducibility(mut self, enabled: bool) -> Self {
588 self.settings.enable_reproducibility = enabled;
589 self.modified_at = Utc::now();
590 self
591 }
592
593 pub fn add_experiment(&mut self, experiment: Experiment) -> Result<()> {
595 self.experiments.push(experiment);
596 self.modified_at = Utc::now();
597 Ok(())
598 }
599
600 pub fn add_publication(&mut self, publication: Publication) -> Result<()> {
602 self.publications.push(publication);
603 self.modified_at = Utc::now();
604 Ok(())
605 }
606
607 pub fn generate_summary_report(&self) -> String {
609 let mut report = String::new();
610
611 report.push_str(&format!("# {}\n\n", self.name));
612 report.push_str(&format!("**Description**: {}\n\n", self.description));
613 report.push_str(&format!("**Research Area**: {:?}\n\n", self.research_area));
614 report.push_str(&format!("**Status**: {:?}\n\n", self.status));
615
616 report.push_str("## Researchers\n\n");
617 for researcher in &self.researchers {
618 report.push_str(&format!(
619 "- {} ({}) - {:?}\n",
620 researcher.name, researcher.email, researcher.role
621 ));
622 }
623
624 if let Some(funding) = &self.funding {
625 report.push_str("\n## Funding\n\n");
626 report.push_str(&format!("**Agency**: {}\n", funding.agency));
627 report.push_str(&format!("**Grant**: {}\n", funding.grant_number));
628 if let Some(amount) = funding.amount {
629 report.push_str(&format!("**Amount**: {:.2} {}\n", amount, funding.currency));
630 }
631 }
632
633 report.push_str("\n## Progress\n\n");
634 report.push_str(&format!("**Experiments**: {}\n", self.experiments.len()));
635 report.push_str(&format!("**Publications**: {}\n", self.publications.len()));
636 report.push_str(&format!(
637 "**Milestones**: {}\n",
638 self.timeline.milestones.len()
639 ));
640
641 report
642 }
643}
644
645impl Default for ProjectSettings {
646 fn default() -> Self {
647 Self {
648 enable_reproducibility: true,
649 enable_backups: true,
650 backup_frequency_hours: 24,
651 data_retention_days: 1095, privacy_settings: PrivacySettings::default(),
653 collaboration_settings: CollaborationSettings::default(),
654 publication_settings: PublicationSettings::default(),
655 }
656 }
657}
658
659impl Default for PrivacySettings {
660 fn default() -> Self {
661 Self {
662 visibility: ProjectVisibility::Private,
663 data_sharing: DataSharingPolicy::OnRequest,
664 allow_anonymous_access: false,
665 embargo_period_days: Some(365),
666 }
667 }
668}
669
670impl Default for CollaborationSettings {
671 fn default() -> Self {
672 Self {
673 enable_realtime_collaboration: true,
674 enable_version_control: true,
675 enable_peer_review: true,
676 enable_discussions: true,
677 max_collaborators: Some(20),
678 }
679 }
680}
681
682impl Default for PublicationSettings {
683 fn default() -> Self {
684 Self {
685 default_format: PublicationFormat::LaTeX,
686 enable_auto_citations: true,
687 citation_style: CitationStyle::IEEE,
688 enable_preprints: true,
689 target_venues: Vec::new(),
690 }
691 }
692}
693
694impl ResearchProjectManager {
695 pub fn new(storage_dir: PathBuf) -> Result<Self> {
697 std::fs::create_dir_all(&storage_dir)?;
698
699 Ok(Self {
700 projects: HashMap::new(),
701 storage_dir,
702 settings: ManagerSettings::default(),
703 })
704 }
705
706 pub fn create_project(&mut self, name: &str) -> Result<&mut ResearchProject> {
708 if self.projects.contains_key(name) {
709 return Err(OptimError::InvalidConfig(format!(
710 "Project '{}' already exists",
711 name
712 )));
713 }
714
715 let project = ResearchProject::new(name);
716 self.projects.insert(name.to_string(), project);
717 self.save_project(name)?;
718
719 Ok(self.projects.get_mut(name).unwrap())
720 }
721
722 pub fn load_project(&mut self, name: &str) -> Result<&mut ResearchProject> {
724 if !self.projects.contains_key(name) {
725 let project_file = self.storage_dir.join(format!("{}.json", name));
726 if project_file.exists() {
727 let content = std::fs::read_to_string(&project_file)?;
728 let project: ResearchProject = serde_json::from_str(&content)?;
729 self.projects.insert(name.to_string(), project);
730 } else {
731 return Err(OptimError::InvalidConfig(format!(
732 "Project '{}' not found",
733 name
734 )));
735 }
736 }
737
738 Ok(self.projects.get_mut(name).unwrap())
739 }
740
741 pub fn save_project(&self, name: &str) -> Result<()> {
743 if let Some(project) = self.projects.get(name) {
744 let project_file = self.storage_dir.join(format!("{}.json", name));
745 let content = serde_json::to_string_pretty(project)?;
746 std::fs::write(&project_file, content)?;
747 }
748
749 Ok(())
750 }
751
752 pub fn list_projects(&self) -> Vec<&str> {
754 self.projects.keys().map(|s| s.as_str()).collect()
755 }
756
757 pub fn delete_project(&mut self, name: &str) -> Result<()> {
759 self.projects.remove(name);
760 let project_file = self.storage_dir.join(format!("{}.json", name));
761 if project_file.exists() {
762 std::fs::remove_file(&project_file)?;
763 }
764
765 Ok(())
766 }
767}
768
769impl Default for ManagerSettings {
770 fn default() -> Self {
771 Self {
772 default_template: None,
773 auto_save_frequency: 15, enable_cloud_backup: false,
775 cloud_provider: None,
776 notifications: NotificationSettings::default(),
777 }
778 }
779}
780
781impl Default for NotificationSettings {
782 fn default() -> Self {
783 Self {
784 email_enabled: true,
785 slack_enabled: false,
786 webhook_url: None,
787 frequency: NotificationFrequency::Daily,
788 }
789 }
790}
791
792#[cfg(test)]
793mod tests {
794 use super::*;
795 use tempfile::tempdir;
796
797 #[test]
798 fn test_research_project_creation() {
799 let project = ResearchProject::new("Test Project")
800 .description("A test research project")
801 .research_area(ResearchArea::MachineLearning)
802 .add_researcher("Dr. Test", "test@example.com")
803 .enable_reproducibility(true);
804
805 assert_eq!(project.name, "Test Project");
806 assert_eq!(project.description, "A test research project");
807 assert_eq!(project.research_area, ResearchArea::MachineLearning);
808 assert_eq!(project.researchers.len(), 1);
809 assert!(project.settings.enable_reproducibility);
810 }
811
812 #[test]
813 fn test_project_manager() {
814 let temp_dir = tempdir().unwrap();
815 let mut manager = ResearchProjectManager::new(temp_dir.path().to_path_buf()).unwrap();
816
817 let project = manager.create_project("Test Project").unwrap();
818 project.description = "Test description".to_string();
819
820 manager.save_project("Test Project").unwrap();
821
822 let projects = manager.list_projects();
823 assert!(projects.contains(&"Test Project"));
824
825 manager.delete_project("Test Project").unwrap();
826 let projects = manager.list_projects();
827 assert!(!projects.contains(&"Test Project"));
828 }
829}