private static void Init() { pausing = true; TextWriter tw; if (GUIenabled) { // Get and update the program run number. try { TextReader tr = new StreamReader(@"C:\RhythmcatScreenshots\config.txt"); string numStr = tr.ReadToEnd().Trim(); tr.Close(); programRunNum = int.Parse(numStr) + 1; } catch { programRunNum = 1; } tw = new StreamWriter(@"C:\RhythmcatScreenshots\config.txt", false); tw.WriteLine(programRunNum); tw.Close(); } workspace = new Workspace(programRunNum, GUIenabled, curMelodyIndex); coderack = new Coderack(workspace); slipnet = new Slipnet(coderack, workspace); workspace.Coderack = coderack; workspace.Slipnet = slipnet; coderack.Slipnet = slipnet; // todo must be in this order to get coderack and slipnet linked to each other. if (GUIenabled) { workspace.CreateTheForms(); } // Reset the big objects. workspace.Reset(); coderack.Reset(); slipnet.Reset(); if (GUIenabled) { workspace.frmWorkspace.setProgramSpeedEvent += new EventHandler <WorkspaceForm.SetProgramSpeedEventArgs>(frmWorkspace_setProgamSpeedEvent); workspace.frmWorkspace.setDetailLevelEvent += new EventHandler <WorkspaceForm.SetDetailLevelEventArgs>(frmWorkspace_setDetailLevelEvent); workspace.frmWorkspace.restartEvent += new EventHandler <WorkspaceForm.RestartEventArgs>(frmWorkspace_restartEvent); workspace.frmWorkspace.pauseEvent += new EventHandler <EventArgs>(frmWorkspace_pauseEvent); workspace.Close += new EventHandler <EventArgs>(workspace_Close); } List <Assembly> assemblies = new List <Assembly>(); // the list of assemblies containing codelets. assemblies.Add(Assembly.GetExecutingAssembly()); // Adds the musicat assembly. //assemblies.Add(Assembly.GetAssembly(typeof(MeasureLinkerCodelet))); // Add the Codelets assembly. // Prepopulate the coderack with the codelets found in the source code tagged with the CodeletAttribute. coderack.Assemblies = assemblies; coderack.Populate(); if (GUIenabled) { // Write a file containing the list of active codelets for this run. tw = new StreamWriter(string.Format(@"C:\RhythmcatScreenshots\codelets-run-{0}.txt", programRunNum), false); foreach (string name in coderack.GetActiveCodeletNames()) { tw.WriteLine(name); } tw.Close(); } // Setup the slipnet. slipnet.Initialize(); if (GUIenabled) { Thread.Sleep(100); lock (restartLock) { if (!restarting) { workspace.Draw(coderack); } } } }
static void Main(string[] args) { // Parse command-line args foreach (string arg in args) { if (arg == "noGUI") { GUIenabled = false; Console.WriteLine("No GUI"); } else if (arg.StartsWith("input=")) { input = arg.Substring(6, arg.Length - 6); inputFromCommandLine = true; Console.WriteLine("Input set to: " + input); } else if (arg.StartsWith("png=")) { pngFilePath = arg.Substring(4, arg.Length - 4); Console.WriteLine("Output .png: " + pngFilePath); } else if (arg.StartsWith("width=")) { pngWidth = int.Parse(arg.Substring(6, arg.Length - 6)); Console.WriteLine("Output width: " + pngWidth.ToString()); } else if (arg.StartsWith("height=")) { pngHeight = int.Parse(arg.Substring(7, arg.Length - 7)); Console.WriteLine("Output height: " + pngHeight.ToString()); } else if (arg.StartsWith("seed=")) { int seed = int.Parse(arg.Substring(5, arg.Length - 5)); Utilities.InitRandom(seed); Console.WriteLine("Random seed: " + pngHeight.ToString()); // Arguments for automatic testing and % correct reporting. } else if (arg.StartsWith("inputExampleName=")) { inputExampleName = arg.Substring(17, arg.Length - 17); Console.WriteLine("inputExampleName set to: " + inputExampleName); } else if (arg.StartsWith("testFile=")) { testFile = arg.Substring(9, arg.Length - 9); groundTruthTesting = true; Console.WriteLine("testFile set to: " + testFile); } else if (arg.StartsWith("resultFile=")) { resultFile = arg.Substring(11, arg.Length - 11); if (!File.Exists(resultFile)) { StreamWriter sw = File.CreateText(resultFile); sw.Close(); } Console.WriteLine("resultFile set to: " + resultFile); } else { throw new ArgumentException("Unknown command-line argument: " + arg); } } if (!GUIenabled && pngFilePath == null && !groundTruthTesting) { throw new ArgumentException("png argument required to set filepath"); } // Parse the file and set input if groundTruth testing if (groundTruthTesting) { Utilities.LogtoFile("GroundTruthTesting: " + DateTime.Now.ToString()); int numRepetitions; List <GroundTruthExample> groundTruthExamples; Parser.Parse(testFile, out numRepetitions, out groundTruthExamples); foreach (GroundTruthExample e in groundTruthExamples) { if (e.name == inputExampleName) { groundTruthExample = e; break; } } if (groundTruthExample.name != inputExampleName) { throw new Exception("Example name not found in ground truth file: " + inputFromCommandLine); } input = groundTruthExample.input; Utilities.LogtoFile("Input: " + input); } if (!GUIenabled) { restarting = false; } else { restarting = true; } if (GUIenabled) { Console.WindowHeight = 40; Console.BufferHeight = 3000; } try { // Verify screenshot path exists. System.IO.Directory.CreateDirectory(Constants.SCREENSHOT_PATH); while (true) //exectues once for each run of the program on an input { Init(); if (!GUIenabled) { pausing = false; } // Set the default input unless we reset with a different input. if (!GUIenabled || !restarting) { // } else { // Clear the restart flag, but leave the input alone. restarting = false; } // Parse the input measures. int upbeatOffset; Key key; List <Measure> parsedMeasures = Rhythm.ParseRhythmMeasures(workspace, input, out upbeatOffset, out key); workspace.Key = key; foreach (Measure m in parsedMeasures) { workspace.measuresInput.Add(m); } workspace.upbeatOffset = upbeatOffset; List <Measure> shiftedMeasures = Rhythm.ShiftRhythmMeasures(workspace, parsedMeasures, upbeatOffset); foreach (Measure m in shiftedMeasures) { workspace.measuresInputShifted.Add(m); } // If there is an upbeat, add the upbeat measure for drawing. Measure newDrawingMeasure = null; Measure drawingMeasureSource = null; int nextDrawingAttackPointIndex = 0; // has to be outside of measure loop because drawing meausre have a different span. int nextDrawingAttackPoint = 0; if (upbeatOffset > 0) { workspace.measuresDrawing.Add(new Measure(workspace.measuresInput[0])); newDrawingMeasure = workspace.measuresDrawing[0]; newDrawingMeasure.ClearNotes(); drawingMeasureSource = workspace.measuresInput[0]; nextDrawingAttackPoint = drawingMeasureSource.rhythm.AttackPointsIncludingRests[0] - upbeatOffset; } int numSixteenthsTotal = Constants.NUM_EXTRA_MEASURES_COMPUTATION * 16; foreach (Measure m in workspace.measuresInput) { numSixteenthsTotal += m.MeasureDuration; } workspace.MaxPossibleTime = Constants.NUM_CODELETS_PER_SIXTEENTH * numSixteenthsTotal - 1; if (groundTruthTesting) { //Utilities.LogtoFile("Ground truth testing: # measuresInput=" + workspace.measuresInput.Count.ToString()); Utilities.LogtoFile("Ground truth testing: input = " + input); } #region Main Loop! // Run N codelets for each measure int i; for (i = 0; i < workspace.measuresInput.Count + Constants.NUM_EXTRA_MEASURES_COMPUTATION; i++) { if (restarting) { break; } workspace.expectations.CleanExpectations(); if (GUIenabled) { lock (restartLock) { if (restarting) { break; } workspace.Draw(coderack); TakeScreenshot(i + 1); } } int nextAttackPointShifted = 0; int nextAttackPointIndex = 0; Measure newShiftedMeasure = null; Measure shiftedMeasureSource = null; if (i < workspace.measuresInputShifted.Count) { shiftedMeasureSource = workspace.measuresInputShifted[i]; } else { if (workspace.measuresInputShifted.Count > 0) { shiftedMeasureSource = workspace.measuresInputShifted[workspace.measuresInputShifted.Count - 1]; } } int codeletsPerMeasure = 0; if (shiftedMeasureSource != null) { codeletsPerMeasure = Constants.NUM_CODELETS_PER_SIXTEENTH * shiftedMeasureSource.MeasureDuration; } // Run N codelets (60) per sixteenth note. for (int j = 0; j < codeletsPerMeasure && !restarting; j++) { while (pausing) { //if (groundTruthTesting) // Utilities.LogtoFile("****************************** PAUSING in ground truth testing"); Thread.Sleep(100); //Application.DoEvents(); } lock (restartLock) { if (restarting) { break; } if (GUIenabled) { workspace.frmWorkspace.SetCodeletNum(workspace.CurrentTime); } coderack.RunNextCodelet(); } workspace.CurrentTime++; // Add measures and notes as time passes. // This got messey due to maintaining the drawing and internal shifted // versions for upbeat measures. Rewrite with less duplication would // be preferable, but it works for now. Note that the shifted version // has a different set of notes and attacks and durations, due to // mandatory breaking-up of long notes crossing barlines. #region Add Measures and Notes // We will add notes if we reached a new attack point. But first create empty measures as needed. // Add a shifted measure if necessary. if (j == 0 && i < workspace.measuresInputShifted.Count) { workspace.measures.Add(new Measure(shiftedMeasureSource)); newShiftedMeasure = workspace.measures[workspace.measures.Count - 1]; newShiftedMeasure.ClearNotes(); } // Add a drawing measure if necessary. //if (j == ((workspace.measuresInput[1].MeasureDuration - upbeatOffset) % workspace.measuresInput[1].MeasureDuration) * Constants.NUM_CODELETS_PER_SIXTEENTH) { if (j == upbeatOffset * Constants.NUM_CODELETS_PER_SIXTEENTH) { drawingMeasureSource = null; if (upbeatOffset > 0) { if (i + 1 < workspace.measuresInput.Count) { drawingMeasureSource = workspace.measuresInput[i + 1]; } } else if (i < workspace.measuresInput.Count) { drawingMeasureSource = workspace.measuresInput[i]; } if (drawingMeasureSource != null) { workspace.measuresDrawing.Add(new Measure(drawingMeasureSource)); newDrawingMeasure = workspace.measuresDrawing[workspace.measuresDrawing.Count - 1]; newDrawingMeasure.ClearNotes(); nextDrawingAttackPointIndex = 0; nextDrawingAttackPoint = drawingMeasureSource.rhythm.AttackPointsIncludingRests[0]; } } // Check for an attack point for the shifted measure. if (j == nextAttackPointShifted * Constants.NUM_CODELETS_PER_SIXTEENTH) { // If we aren't in the extra measures yet, add note to drawing and shifted measures. if (i < workspace.measuresInputShifted.Count) { // Add note. newShiftedMeasure.rhythm.AddNote(shiftedMeasureSource.rhythm.notes[nextAttackPointIndex]); // Increment attack point. nextAttackPointIndex++; if (nextAttackPointIndex < shiftedMeasureSource.rhythm.AttackPointsIncludingRests.Count) { nextAttackPointShifted = shiftedMeasureSource.rhythm.AttackPointsIncludingRests[nextAttackPointIndex]; } } } // Check for an attack point for the drawing measure. if (j == (((nextDrawingAttackPoint + upbeatOffset) * Constants.NUM_CODELETS_PER_SIXTEENTH) % codeletsPerMeasure)) { // If we aren't in the extra measures yet, add note to drawing and shifted measures. if (i < workspace.measuresInputShifted.Count) { // Add note. newDrawingMeasure.rhythm.AddNote(drawingMeasureSource.rhythm.notes[nextDrawingAttackPointIndex]); // Increment attack point. nextDrawingAttackPointIndex++; if (nextDrawingAttackPointIndex < drawingMeasureSource.rhythm.AttackPointsIncludingRests.Count) { nextDrawingAttackPoint = drawingMeasureSource.rhythm.AttackPointsIncludingRests[nextDrawingAttackPointIndex]; if (workspace.measuresDrawing.Count == 1) { nextDrawingAttackPoint -= upbeatOffset; // correct the upbeat measure's attack points } } } } #endregion if (GUIenabled) { if (workspace.CurrentTime % 15 == 0) { Console.WriteLine("Time = " + workspace.CurrentTime.ToString()); } lock (restartLock) { if (restarting) { break; } if (workspace.CurrentTime % NUM_CODELETS_UNTIL_DRAW == 0) { workspace.Draw(coderack); } } } // Update the slipnet every 15 codelets. if (workspace.CurrentTime % Constants.NUM_CODELETS_TILL_SLIPNET_UPDATE == 0) { // Generate list of concept instances from the workspace. List <ConceptInstance> conceptInstances = new List <ConceptInstance>(); /* * foreach (GroupElement ge in workspace.Layers[0].GroupElements) { * // Grab all concept nodes activated above threshold in any perspect lists. * foreach (Perspect p in ge.Perspects) { * conceptInstances.Add(new ConceptInstance(p.ConceptNode, p.Strength)); * } * }*/ slipnet.UpdateActivations(conceptInstances); } // Update the Temperature every 15 codelets. if (workspace.CurrentTime % Constants.NUM_CODELETS_TILL_TEMPERATURE_UPDATE == 0) { // Use the average happiness of structures in the recent window. int max = workspace.MaxLocation; int min = Math.Max(0, max - Constants.NUM_MEASURES_FOR_WORKSPACE_HAPPINESS); workspace.Temperature = workspace.HappinessForRange(min, max); } // Update the coderack every 15 codelets. if (workspace.CurrentTime % Constants.NUM_CODELETS_TILL_CODERACK_UPDATE == 0) { // Add new codelets. coderack.Populate(); coderack.Populate(); } // Clean out old codelets every 15 codelets. if (workspace.CurrentTime % Constants.NUM_CODELETS_TILL_CODERACK_CLEANUP == 0) { // Remove oldest codelets until the coderack is the maximum size. coderack.RemoveOld(); } // Fade old links, relationships every 15 codelets. if (workspace.CurrentTime % Constants.NUM_CODELETS_TILL_LINK_FADE == 0) { // Remove oldest codelets until the coderack is the maximum size. workspace.WeakenOldLinks(); } // Dump in more high-level codelets every 30 codelets. if (workspace.CurrentTime % Constants.NUM_CODELETS_TILL_NEW_HIGH_LEVEL == 0) { AddHighLevelCodelets(i); } if (GUIenabled) { Thread.Sleep(TIME_TO_SLEEP_BETWEEN_CODELETS); } } // Done with a measure. if (restarting) { //if (groundTruthTesting) // Utilities.LogtoFile("****************************** RESTART in ground truth testing"); break; } if (GUIenabled) { // Show coderack. //Console.WriteLine("Coderack:"); //Console.WriteLine(codeRack.ToString()); Console.WriteLine("Workspace:"); Console.WriteLine(workspace.ToString()); Console.WriteLine(slipnet.ToString()); } } // Done with all measures! #endregion // DONE with run! // Clear future expectations. workspace.expectations.RemoveAllExpectations(); // Final draw of everything. workspace.Draw(coderack); // Final screenshot w/o expectations. TakeScreenshot(i + 1); // Finally generate the graphical output if we're in noGUI mode and not doing groundTruthTesting. if (!GUIenabled & !groundTruthTesting) { int width = DEFAULT_OUTPUT_WIDTH, height = DEFAULT_OUTPUT_HEIGHT; Bitmap bmp = new Bitmap(width, height); Graphics graphics = Graphics.FromImage(bmp); WorkspaceForm.DrawWorkspaceToContext(graphics, width, height, workspace, 0, false, false, bmp); // Now scale to desired size. Bitmap bmpScaled = new Bitmap(bmp, pngWidth, pngHeight); bmpScaled.Save(pngFilePath, System.Drawing.Imaging.ImageFormat.Png); return; } // Compute results and store to file if we're going GT testing. if (groundTruthTesting) { // Check groups. int totalNumGroupsFound; if (!ESSEN_TESTING) { totalNumGroupsFound = workspace.groups.Count; } else { // Only count strong normal (non-meta) groups in Essen testing. totalNumGroupsFound = 0; foreach (Group g in workspace.groups) { if (g.Level == 1 && g.ComputeStrength() > 20) { totalNumGroupsFound++; } } } int numMissingGroups = 0; foreach (GroundTruth.ExpectedGroup eg in groundTruthExample.groups) { // Try to find the expected group. bool found = false; foreach (Group g in workspace.groups) { if (g.MinLocation == eg.startMeasure && g.MaxLocation == eg.endMeasure) { found = true; break; } } if (!found) { numMissingGroups++; } } // Check analogies. int totalNumAnalogiesFound = workspace.analogies.Count; int numMissingAnalogies = 0; foreach (GroundTruth.ExpectedAnalogy ea in groundTruthExample.analogies) { // Try to find the expected group. bool found = false; foreach (Analogy a in workspace.analogies) { if (a.LHS.MinLocation == ea.LHS.startMeasure && a.LHS.MaxLocation == ea.LHS.endMeasure && a.RHS.MinLocation == ea.RHS.startMeasure && a.RHS.MaxLocation == ea.RHS.endMeasure) { found = true; break; } } if (!found) { numMissingAnalogies++; } } // Write to disk. Format: // # expected groups, # missing, #expected analogies, #missing, timestamp // Lock results file in case we run multiple musicats at once. bool retry = true; int retries = 10; while (retry) { retry = false; Utilities.LogtoFile("Avg ms: " + workspace.Coderack.AvgCodeletRunTimeMs.ToString() + "\tavg age at run: " + workspace.Coderack.AverageCodeletAgeAtRun.ToString() + "\t% Killed: " + workspace.Coderack.PercentCodeletsKilled.ToString() + "\ttimestep at end: " + workspace.CurrentTime.ToString() + "\t#measures in workspaceShifted: " + workspace.measuresInputShifted.Count.ToString()); try { FileStream fileStream = new FileStream(resultFile, FileMode.Append, FileAccess.Write, FileShare.None); using (TextWriter tw = new StreamWriter(fileStream)) { tw.WriteLine("{0},{1},{2},{3},{4},{5},{6}", groundTruthExample.groups.Count, numMissingGroups, groundTruthExample.analogies.Count, numMissingAnalogies, DateTime.Now.ToString(), totalNumGroupsFound, totalNumAnalogiesFound); } } catch (FileNotFoundException Ex) { // The file didn't exist MessageBox.Show("Didn't exist:" + Ex.ToString()); } catch (AccessViolationException Ex) { // You don't have the permission to open this MessageBox.Show("Access violation: " + Ex.ToString()); } catch (IOException Ex) { // IO exception -- try a few more times. if (retries > 0) { retry = true; retries--; } else { MessageBox.Show("Max retries reached: IO exception: " + Ex.ToString()); } Thread.Sleep(20); } catch (Exception Ex) { // Something happened! MessageBox.Show("Unexpected exception: " + Ex.ToString()); } } return; // done with ground truth testing! } // Wait until reset event happens while (!restarting) { Thread.Sleep(100); //Application.DoEvents(); } curMelodyIndex = workspace.frmWorkspace.MelodyIndex; workspace.CloseForms(); //Console.Read(); } } catch (Exception e) { Utilities.LogtoFile(e.ToString()); #if DEBUG throw e; #else MessageBox.Show(e.ToString()); #endif } }