int main(){ makeFileCopy("tests.log", "temp.txt"); //================================================================================ header("File Loading"); ExpHourCalc *expHourCalc = new ExpHourCalc(); GatheringLog *gatheringLog = new GatheringLog(); LogFileParser *fileNotExist = new LogFileParser("sdlfkjskldfj"); doTest("LogFileParser with invalid logfile input", fileNotExist->isOK, false); LogFileParser *parser = new LogFileParser("temp.txt"); parser->setExpHourCalc(expHourCalc); parser->setGatheringLog(gatheringLog); doTest("LogFileParser with valid logfile", parser->isOK, true); //ExpHourCalc *failtest = new ExpHourCalc("sldfkjslkdfj"); //doTest("ExpHourCalc init failtest", failtest->isOK, false); //ExpHourCalc *expHourCalc = new ExpHourCalc("temp.txt"); //doTest("ExpHourCalc init expHourCalc", expHourCalc->isOK, true); doTest("Level 1 exp", expHourCalc->getExpChartEntry(1), 400); doTest("Level 65 exp", expHourCalc->getExpChartEntry(65), 584561235); //================================================================================ header("XP / AP Gain"); expHourCalc->start(-1, -1, -1); appendFile("temp.txt", "2013.06.27 23:35:36 : Critical Hit!You inflicted 944 damage on Wori by using Righteous Punishment I. "); appendFile("temp.txt", "2013.06.27 23:35:36 : You have gained 1,008 Abyss Points. "); appendFile("temp.txt", "2013.06.27 23:35:36 : You have gained 8,867 XP from Wori. "); appendFile("temp.txt", "2013.06.27 23:35:36 : You have defeated Wori. "); appendFile("temp.txt", "2013.06.27 23:35:36 : Invalid target. "); parser->processLines(); cout << endl << "No level, xp, or ap input" << endl; doTest("exp: ", expHourCalc->expGained, 8867); //doTest("formatted exp display", expHour cout << endl << "XP + AP gain" << endl; doTest("XP: ", expHourCalc->expGained, 8867); doTest("AP: ", expHourCalc->apGained, 1008); doTest("last tick XP", expHourCalc->lastExpPacket, 8867); doTest("last tick AP", expHourCalc->lastApPacket, 1008); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); doTest("numExpPacketsOnLastChange", expHourCalc->numExpPacketsOnLastChange, 1); doTest("numApPacketsOnLastChange", expHourCalc->numApPacketsOnLastChange, 1); doTest("currentExp", expHourCalc->currentExp, -1); doTest("currentAp", expHourCalc->currentExp, -1); doTest("getLastExpPacketPercent", expHourCalc->getLastExpPacketPercent(), 0); doTest("getLastApPacketPercent", expHourCalc->getLastApPacketPercent(), 0); doTest("getExpChartEntry", expHourCalc->getExpChartEntry(expHourCalc->level), -1); doTest("getNextRankAp", expHourCalc->getNextRankAp(), -1); cout << endl << "Quest EXP with repose" << endl; appendFile("temp.txt", "2013.06.27 22:17:33 : Roadhouse recovered 183 MP due to the effect of Strong Instant Recovery. "); appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 20,052,999 XP from Vard (Energy of Repose 10,405). "); appendFile("temp.txt", "2013.06.27 22:17:34 : Quest complete: Kata-where? "); appendFile("temp.txt", "2013.06.27 22:17:34 : Quest updated: For the Dead "); parser->processLines(); doTest("exp gained: ", expHourCalc->expGained, 20052999 + 8867); doTest("repose consumed: ", expHourCalc->reposeExp, 10405); doTest("currentExp", expHourCalc->currentExp, -1); doTest("getLastExpPacketPercent", expHourCalc->getLastExpPacketPercent(), 0); cout << endl << "Strong repose" << endl; expHourCalc->reset(); appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 200,000 XP from Vard (Strong Energy of Repose 100,000). "); parser->processLines(); doTest("Strong exp gained: ", expHourCalc->expGained, 200000); doTest("Strong repose consumed: ", expHourCalc->reposeExp, 100000); //================================================================================ header("Repose + salvation"); expHourCalc->reset(); expHourCalc->level = 20; expHourCalc->expGained = 5000; expHourCalc->currentExp = 12000; appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 15,411 XP from Studio Butler (Energy of Repose 3,626, Energy of Salvation 2,719)."); parser->processLines(); doTest("current exp: ", expHourCalc->currentExp, 27411); doTest("exp gained: ", expHourCalc->expGained, 20411); doTest("repose consumed: ", expHourCalc->reposeExp, 3626); doTest("salvation consumed: ", expHourCalc->salvationExp, 2719); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); doTest("numExpPacketsOnLastChange", expHourCalc->numExpPacketsOnLastChange, 1); doTest("numApPacketsOnLastChange", expHourCalc->numApPacketsOnLastChange, 0); expHourCalc->reset(); cout << endl << "Strong Repose + salvation" << endl; appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 23,000 XP from Studio Butler (Strong Energy of Repose 10,000, Energy of Salvation 3,000)."); parser->processLines(); doTest("exp gained: ", expHourCalc->expGained, 23000); doTest("strong repose consumed: ", expHourCalc->reposeExp, 10000); doTest("salvation consumed: ", expHourCalc->salvationExp, 3000); expHourCalc->reset(); cout << endl << "Salvation only" << endl; appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 13.000.000 XP from s u p e r c h a r g e d (Energy of Salvation 3.000.000)."); parser->processLines(); doTest("exp gained: ", expHourCalc->expGained, 13000000); doTest("salvation consumed: ", expHourCalc->salvationExp, 3000000); appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 6666 XP from f*****g piece of shit (Energy of Salvation 666)."); parser->processLines(); doTest("Additional salvation consumed: ", expHourCalc->salvationExp, 3000000 + 666); //================================================================================ expHourCalc->reset(); header("With level and starting exp, gathering"); expHourCalc->level = 20; expHourCalc->currentExp = 12000; appendFile("temp.txt", "2013.07.29 23:55:28 : You have started gathering Ancient Aether."); appendFile("temp.txt", "2013.07.02 01:25:12 : You have acquired [item:152000916;ver4;;;;]. "); appendFile("temp.txt", "2013.07.02 01:25:12 : You have gained 7,580 XP. "); appendFile("temp.txt", "2013.07.02 01:25:12 : You have gained experience from gathering. "); appendFile("temp.txt", "2013.07.02 01:25:12 : You have started gathering Pure Ancient Aether. "); parser->processLines(); doTest("new exp value: ", expHourCalc->currentExp, 19580); doTest("new exp gained: ", expHourCalc->expGained, 7580); expHourCalc->reset(); header("Level up exp rollover"); expHourCalc->level = 5; expHourCalc->currentExp = 7000; appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 2,000 XP from Vard."); parser->processLines(); doTest("char exp", expHourCalc->currentExp, 7000 + 2000 - 8601); doTest("total exp gained", expHourCalc->expGained, 2000); doTest("char lvl", expHourCalc->level, 6); //================================================================================ header("Pre ascension exp waste"); expHourCalc->reset(); expHourCalc->level = 9; expHourCalc->currentExp = 10000; appendFile("temp.txt", "2013.06.28 09:42:49 : Quest updated: Ascension "); appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned the Essencetapping skill. "); appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned the Morph Substances skill. "); appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned [recipe_ex:155005001;DeleteAfterAscen-IS]. "); appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned [recipe_ex:155005002;DeleteAfterAscen-IS]. "); appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned [recipe_ex:155005005;DeleteAfterAscen-IS]. "); appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned the Aethertapping skill. "); appendFile("temp.txt", "2013.06.28 09:42:50 : [3.LFG] [charname:Onimushaz-SL;1.0000 0.6941 0.6941]: [cmd:rGSlNwGJGRxRQv03cJhj8zmbH1pS5sI2+Ojm4GyCo/tFUYOZnylZ5HCClET+4/tCS7qtaOGT6oZDfpuNO+D18g==]Adma Rush Need Cleric at Lannok "); appendFile("temp.txt", "2013.06.28 09:42:57 : [3.LFG] [charname:Draizon-KR;1.0000 0.6941 0.6941]: [cmd:ZuRJ77suA3HGXknXXvlwhpPM8QnGQsOkmk/KeMfcfBdFUYOZnylZ5HCClET+4/tC4UL+Ir0PulB5jOt1gqsgzQ==]NTC need all! "); appendFile("temp.txt", "2013.06.28 09:43:01 : [3.LFG] [charname:Demolize-TM;1.0000 0.6941 0.6941]: [cmd:P4LwuGgTZY+ycKKEACMJvuAyWLtXF0rdZGbvQ8Z9+DdFUYOZnylZ5HCClET+4/tCg5pior9yCPYe0vyEXekmgw==]?BT?NEED ALL 59+ ?? Hard Mode "); appendFile("temp.txt", "2013.06.28 09:43:04 : You have gained 73,200 XP from Munin. "); appendFile("temp.txt", "2013.06.28 09:43:04 : You can advance to level 10 only after you have completed the class change quest. "); parser->processLines(); doTest("char exp", expHourCalc->currentExp, 43087); doTest("char level", expHourCalc->level, 9); doTest("exp gained", expHourCalc->expGained, 33087); expHourCalc->currentExp = 43087; appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 2,000 XP from Vard."); appendFile("temp.txt", "2013.06.27 09:43:04 : You can advance to level 10 only after you have completed the class change quest. "); parser->processLines(); doTest("char exp", expHourCalc->currentExp, 43087); doTest("char level", expHourCalc->level, 9); cout << endl << "Ascended" << endl; appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 2,000 XP from Vard."); parser->processLines(); doTest("char exp", expHourCalc->currentExp, 2000); doTest("char level", expHourCalc->level, 10); //================================================================================ header("Fast Track Server level cap exp waste"); expHourCalc->reset(); expHourCalc->level = 55; expHourCalc->currentExp = 103225345; appendFile("temp.txt", "2013.09.23 22:26:04 : You have used Inggison Illusion Fortress Scroll. "); appendFile("temp.txt", "2013.09.23 22:26:13 : aasfer-IS was affected by its own Aion's Favor I. "); appendFile("temp.txt", "2013.09.23 22:26:15 : Quest updated: [Coin] For the Scholars "); appendFile("temp.txt", "2013.09.23 22:26:20 : You have acquired 5 [item:186000018;ver4;;;;]s and stored them in your special cube. "); appendFile("temp.txt", "2013.09.23 22:26:20 : You have gained 4,186,683 XP from Eduardo. "); appendFile("temp.txt", "2013.09.23 22:26:20 : You cannot be Level 56 on the Fast-Track Server. "); appendFile("temp.txt", "2013.09.23 22:26:20 : Quest complete: [Coin] For the Scholars "); parser->processLines(); doTest("char exp", expHourCalc->currentExp, 104225345); doTest("char level", expHourCalc->level, 55); doTest("exp gained", expHourCalc->expGained, 1000000); //================================================================================ header("Level cap exp waste"); expHourCalc->reset(); expHourCalc->level = 65; expHourCalc->currentExp = 10000000; appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 20,052,999 XP from Vard (Energy of Repose 10,405). "); parser->processLines(); doTest("char exp", expHourCalc->currentExp, 30052999); doTest("exp gained", expHourCalc->expGained, 20052999); doTest("last exp packet", expHourCalc->lastExpPacket, 20052999); doTest("char level", expHourCalc->level, 65); doTest("repose consumed", expHourCalc->reposeExp, 10405); expHourCalc->reset(); expHourCalc->level = 65; expHourCalc->currentExp = 584561235; appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 20,052,999 XP from Vard (Energy of Repose 10,405). "); parser->processLines(); doTest("char exp", expHourCalc->currentExp, 584561235); doTest("exp gained", expHourCalc->expGained, 0); doTest("last exp packet", expHourCalc->lastExpPacket, 20052999); doTest("char level", expHourCalc->level, 65); doTest("repose consumed", expHourCalc->reposeExp, 10405); //================================================================================ header("Soul Healing / EXP loss on death"); expHourCalc->reset(); //lv 13 //61581 xp //die //58595 //551 zeny //gain 2171 //60766 xp //60766 //57510 //59681 //lv 43 //21,016,061 //die //20,648,891 //18022 zeny //gain 244780 //20,893,671 cout << "lv 13 exp 61851" << endl; expHourCalc->level = 13; expHourCalc->currentExp = 61851; appendFile("temp.txt","2013.06.27 23:03:19 : You are no longer bleeding. "); appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); parser->processLines(); doTest("Died to a monster, most likely XP lost, needExpUpdate is true", expHourCalc->needExpUpdate, true); doTest("needApUpdate is false unless there was no XP loss", expHourCalc->needApUpdate, false); appendFile("temp.txt", "2013.07.04 18:15:04 : You spent 551 Kinah."); appendFile("temp.txt", "2013.07.04 18:15:04 : You have gained 2,171 XP. "); appendFile("temp.txt", "2013.07.04 18:15:04 : You received Soul Healing. "); parser->processLines(); doTest("exp change:", expHourCalc->lastExpPacket, -1085); doTest("exp after:", expHourCalc->currentExp, 60766); doTest("zeny spent:", expHourCalc->cashSpent, 551); doTest("last zeny transaction:", expHourCalc->lastCashTransaction, -551); doTest("Soul healing done, needExpUpdate is false", expHourCalc->needExpUpdate, false); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 1085 + 2171); expHourCalc->reset(); cout << "lv 43 exp 21016061" << endl; expHourCalc->level = 43; expHourCalc->currentExp = 21016061; appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); appendFile("temp.txt", "2013.07.04 18:40:23 : You spent 18,022 Kinah. "); appendFile("temp.txt", "2013.07.04 18:40:23 : You have gained 244,780 XP. "); appendFile("temp.txt", "2013.07.04 18:40:23 : You received Soul Healing."); parser->processLines(); doTest("exp change:", expHourCalc->lastExpPacket, -122390); doTest("exp gained so far:", expHourCalc->expGained, -122390); doTest("exp after:", expHourCalc->currentExp, 20893671); doTest("zeny spent:", expHourCalc->cashSpent, 18022); doTest("last zeny transaction:", expHourCalc->lastCashTransaction, -18022); appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); appendFile("temp.txt", "2013.07.04 18:40:23 : You spent 18,022 Kinah. "); appendFile("temp.txt", "2013.07.04 18:40:23 : You have gained 244,780 XP. "); appendFile("temp.txt", "2013.07.04 18:40:23 : You received Soul Healing."); parser->processLines(); doTest("expLostToDeaths after 2 deaths", expHourCalc->expLostToDeaths, (244780 + 122390) * 2); doTest("exp gained so far:", expHourCalc->expGained, -244780); doTest("currentExp:", expHourCalc->currentExp, 20893671 - 122390); //================================================================================ header("1 zeny soul healing -> PKed"); expHourCalc->reset(); expHourCalc->level = 43; expHourCalc->currentExp = 21016061; appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); appendFile("temp.txt","2013.07.05 00:54:59 : Saamn recovered 183 MP due to the effect of Strong Instant Recovery. "); appendFile("temp.txt","2013.07.05 00:54:59 : You have resurrected. "); appendFile("temp.txt","2013.07.05 00:55:02 : [3.LFG] [charname:ImSoBucci;1.0000 0.6941 0.6941]: [cmd:0cWaGV/kjHuy7eO6sQkkLIOFT2cFnzucw1Y29SlJmwZFUYOZnylZ5HCClET+4/tCGl2bZjvYqe8X4QPegOqKKQ==]BTHM LF DPS,TANK,HEALS "); appendFile("temp.txt","2013.07.05 00:55:04 : Demonjon restored 1,940 HP. "); appendFile("temp.txt","2013.07.05 00:55:04 : Demonjon restored 357 MP. "); appendFile("temp.txt","2013.07.05 00:55:09 : You spent 1 Kinah. "); appendFile("temp.txt","2013.07.05 00:55:09 : You received Soul Healing. "); appendFile("temp.txt","2013.07.05 00:55:11 : The weapon has been changed. "); parser->processLines(); doTest("PK soul healing no exp loss check:", expHourCalc->currentExp, 21016061); //================================================================================ header("Clear needExpUpdate if no XP to recover"); expHourCalc->reset(); expHourCalc->level = 44; expHourCalc->currentExp = 10000000; expHourCalc->expGained = 480752; appendFile("temp.txt","2013.07.15 18:24:31 : You can see again "); appendFile("temp.txt","2013.07.15 18:24:31 : You have died. "); appendFile("temp.txt","2013.07.15 16:42:31 : You have resurrected. "); appendFile("temp.txt","2013.07.13 17:11:07 : You do not have any XP to recover. "); doTest("needExpUpdate", expHourCalc->needExpUpdate, false); doTest("needApUpdate", expHourCalc->needApUpdate, false); //================================================================================ header("Manual exp update - pve death"); expHourCalc->reset(); expHourCalc->level = 44; expHourCalc->currentExp = 10000000; expHourCalc->expGained = 480752; appendFile("temp.txt","2013.06.27 20:21:33 : You cannot do that while you are in combat. "); appendFile("temp.txt","2013.06.27 20:21:33 : You have died. "); appendFile("temp.txt","2013.06.27 20:21:49 : You have resurrected. "); appendFile("temp.txt","2013.06.27 20:21:49 : You cannot attack the enemy faction in this region. "); appendFile("temp.txt","2013.06.27 20:22:00 : Suder inflicted 4,192 damage on Training Dummy by using Ritual Push I. "); parser->processLines(); expHourCalc->updateExp(10000000 - 380752); parser->processLines(); doTest("currentExp", expHourCalc->currentExp, 10000000 - 380752); doTest("expGained", expHourCalc->expGained, 100000); doTest("lastExpPacket", expHourCalc->lastExpPacket, -380752); doTest("needExpUpdate", expHourCalc->needExpUpdate, false); doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 380752); appendFile("temp.txt","2013.06.27 20:22:02 : You spent 28,259 Kinah. "); appendFile("temp.txt","2013.06.27 20:22:02 : You have gained 719,902 XP. "); appendFile("temp.txt","2013.06.27 20:22:02 : You received Soul Healing. "); parser->processLines(); doTest("soul heal after manual exp update: currentExp", expHourCalc->currentExp, 10000000 - 380752 + 719902); doTest("needExpUpdate is false", expHourCalc->needExpUpdate, false); doTest("needApUpdate is false", expHourCalc->needApUpdate, false); doTest("lastCashTransaction", expHourCalc->lastCashTransaction, -28259); doTest("cashSpent", expHourCalc->cashSpent, 28259); doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 380752); //================================================================================ header("Abyss Rank"); expHourCalc->currentAp = 1000; doTest("9 kyu test", expHourCalc->getAbyssRankName(), "9 kyu"); expHourCalc->currentAp = 120000; doTest("2 kyu test", expHourCalc->getAbyssRankName(), "2 kyu"); expHourCalc->currentAp = 200000; doTest("200000 AP test", expHourCalc->getAbyssRankName(), "???"); expHourCalc->currentAp = 2000000000; doTest("2 billion AP test", expHourCalc->getAbyssRankName(), "???"); //================================================================================ header("AP Spending"); expHourCalc->reset(); expHourCalc->currentAp = 95000; expHourCalc->apGained = 95000; expHourCalc->lastApPacket = 95000; appendFile("temp.txt","2013.07.03 18:15:39 : Your Abyss Rank has changed to Soldier, Rank 7. "); appendFile("temp.txt","2013.07.03 18:15:39 : You used 89,775 Abyss Points. "); appendFile("temp.txt","2013.07.03 18:15:40 : [3.LFG] [charname:Vladarina;1.0000 0.6941 0.6941]: Asmos, we expect a LOT of elyos to attack [pos:Pradeth;600060000 2676.0 2720.2 0.0 0] tonight. I need everybody (even level 50s) I can get inside of that fort EARLY, before 11 pm est vuln (5 hours). Bind "); appendFile("temp.txt","2013.07.03 18:15:40 : You have purchased [item:140000816;ver4;;;;]. "); parser->processLines(); doTest("AP spent ", expHourCalc->apSpent, 89775); doTest("AP after purchase", expHourCalc->currentAp, 5225); doTest("AP gained after purchase", expHourCalc->apGained, 5225); doTest("last AP Packet", expHourCalc->lastApPacket, -89775); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); //================================================================================ header("Got PKed, need to ask for manual AP update"); expHourCalc->reset(); expHourCalc->currentAp = 100000; appendFile("temp.txt","2013.07.05 16:15:18 : Tip: Elyos and Asmodians cannot fight one another in a neutral zone."); appendFile("temp.txt","2013.07.05 16:15:18 : You may be unable to use certain skills or items in this area. "); appendFile("temp.txt","2013.07.05 16:15:18 : A survey has arrived. Click the icon to open the survey window. "); appendFile("temp.txt","2013.07.05 16:15:20 : You have joined Standard Server. "); appendFile("temp.txt","2013.07.07 00:56:26 : You are no longer silenced. "); appendFile("temp.txt","2013.07.07 00:56:26 : Your movement speed is restored to normal. "); appendFile("temp.txt","2013.07.07 00:56:26 : Your attack speed is restored to normal. "); appendFile("temp.txt","2013.07.07 00:56:26 : You were killed by Thomasbangalter's attack. "); appendFile("temp.txt","2013.07.07 00:56:28 : Noble Energy inflicted 684 damage on Thomasbangalter by using Noble Energy IV. "); appendFile("temp.txt","2013.07.07 00:56:28 : Thomasbangalter inflicted 733 damage on Devios by using Illusion Storm VII. "); parser->processLines(); doTest("I'm on Standard Server", expHourCalc->getCurrentServer(), "Standard"); doTest("Got PKed in standard server, need ap update yes", expHourCalc->needApUpdate, true); doTest("needExpUpdate needs to be false", expHourCalc->needExpUpdate, false); expHourCalc->updateAp(95000); appendFile("temp.txt","2013.06.27 23:03:26 : You have resurrected. "); appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. "); appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. "); parser->processLines(); doTest("already updated AP, don't apupdate again", expHourCalc->needApUpdate, false); appendFile("temp.txt","2013.07.07 00:56:26 : You were killed by Sogyawie's attack. "); appendFile("temp.txt","2013.06.27 23:03:26 : You have resurrected. "); appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. "); appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. "); parser->processLines(); doTest("Got PKed, didn't update AP, soul healed", expHourCalc->needApUpdate, true); header("Got killed in structured PvP, no AP loss, don't ask for update"); expHourCalc->reset(); appendFile("temp.txt","2013.06.25 14:44:14 : You have item(s) left to settle at the Broker. "); appendFile("temp.txt","2013.06.25 14:44:16 : You have joined the group. "); appendFile("temp.txt","2013.06.25 14:44:16 : You have joined Instance Server. "); appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion region channel. "); appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion trade channel. "); appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the LFG Channel. "); appendFile("temp.txt","2013.06.25 14:44:23 : Nekoh-IS has joined your group. "); appendFile("temp.txt","2013.06.25 14:44:24 : You have joined the Templar Channel. "); appendFile("temp.txt","2013.06.27 19:04:58 : You were killed by Mrplatino's attack."); parser->processLines(); doTest("I'm on Instance Server", expHourCalc->getCurrentServer(), "Instance"); doTest("needApUpdate should be false", expHourCalc->needApUpdate, false); header("Got killed in by mobster in structured PvP, manual EXP enter, no EXP or AP loss, don't ask for AP update"); expHourCalc->reset(); expHourCalc->level = 60; expHourCalc->currentExp = 1234567; appendFile("temp.txt","2013.06.25 14:44:14 : You have item(s) left to settle at the Broker. "); appendFile("temp.txt","2013.06.25 14:44:16 : You have joined the group. "); appendFile("temp.txt","2013.06.25 14:44:16 : You have joined Instance Server. "); appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion region channel. "); appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion trade channel. "); appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the LFG Channel. "); appendFile("temp.txt","2013.06.25 14:44:23 : Nekoh-IS has joined your group. "); appendFile("temp.txt","2013.06.25 14:44:24 : You have joined the Templar Channel. "); appendFile("temp.txt","2013.06.27 19:04:58 : You have died. "); parser->processLines(); expHourCalc->updateExp(1234567); parser->processLines(); doTest("needApUpdate should be false", expHourCalc->needApUpdate, false); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 0); doTest("apLostToPk", expHourCalc->apLostToPk, 0); appendFile("temp.txt","2013.07.05 16:15:20 : You have joined Standard Server. "); appendFile("temp.txt","2013.06.27 23:03:19 : You are no longer bleeding. "); appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); parser->processLines(); header("Back to Standard Server, attacked by enemy faction player, finished blow from monster"); doTest("Don't know whether XP was lost or not - needExpUpdate is true", expHourCalc->needExpUpdate, true); appendFile("temp.txt","2013.06.27 23:03:19 : You do not have much flight time left. Please land on a secure place. "); appendFile("temp.txt","2013.06.27 23:03:19 : Pashid Offense Elite Fighter is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Fighter used Conqueror's Passion. "); appendFile("temp.txt","2013.06.27 23:03:19 : Pashid Offense Elite Protector is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Protector used Conqueror's Passion. "); appendFile("temp.txt","2013.06.27 23:03:20 : Pashid Offense Elite Archer is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Archer used Conqueror's Passion. "); appendFile("temp.txt","2013.06.27 23:03:20 : Pashid Offense Elite Archer is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Archer used Conqueror's Passion. "); appendFile("temp.txt","2013.06.27 23:03:20 : Pashid Offense Elite Archer is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Archer used Conqueror's Passion. "); appendFile("temp.txt","2013.06.27 23:03:24 : [charname:Gwc;0.6118 0.9059 0.8627]: gub "); appendFile("temp.txt","2013.06.27 23:03:26 : You have resurrected. "); appendFile("temp.txt","2013.06.27 23:03:50 : [charname:Mystfang;0.6118 0.9059 0.8627]: omg "); appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. "); appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. "); parser->processLines(); doTest("1 zeny soul healing means u lost AP", expHourCalc->needApUpdate, true); doTest("No EXP loss when you lost AP", expHourCalc->needExpUpdate, false); doTest("Soul healing done, needExpUpdate is false", expHourCalc->needExpUpdate, false); expHourCalc->currentExp = 100000; expHourCalc->currentAp = 1000000; header("Manual XP update, EXP unchanged (no exp loss) = possible AP loss"); appendFile("temp.txt","2013.06.27 23:03:19 : You are no longer bleeding. "); appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); parser->processLines(); expHourCalc->updateExp(100000); parser->processLines(); doTest("needApUpdate", expHourCalc->needApUpdate, true); doTest("clear needExpUpdate", expHourCalc->needExpUpdate, false); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); expHourCalc->updateAp(999000); parser->processLines(); doTest("After manual AP update, needExpUpdate false", expHourCalc->needExpUpdate, false); doTest("After manual AP update, needApUpdate false", expHourCalc->needApUpdate, false); doTest("current exp", expHourCalc->currentExp, 100000); doTest("current ap", expHourCalc->currentAp, 999000); doTest("last exp packet", expHourCalc->lastExpPacket, 0); doTest("last ap packet", expHourCalc->lastApPacket, -1000); doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 0); doTest("apLostToPk", expHourCalc->apLostToPk, 1000); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. "); appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. "); parser->processLines(); doTest("After manual AP update, soul healed, don't ask for AP update again", expHourCalc->needApUpdate, false); //================================================================================ header("Promopt for AP update due to AP loss on death"); expHourCalc->reset(); expHourCalc->currentAp = 95000; expHourCalc->apGained = 95000; expHourCalc->lastApPacket = 1234; appendFile("temp.txt","2013.06.27 19:04:58 : You were killed by Mrplatino's attack."); parser->processLines(); cout << endl << "Invalid update" << endl; expHourCalc->updateAp(95001); parser->processLines(); doTest("currentAp after invalid update", expHourCalc->currentAp, 95000); doTest("apGained after invalid update", expHourCalc->apGained, 95000); doTest("lastApPacket after invalid update", expHourCalc->lastApPacket, 1234); doTest("apLostToPk after invalid update", expHourCalc->apLostToPk, 0); doTest("Still need ap update", expHourCalc->needApUpdate, true); doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false); doTest("apLostToPk", expHourCalc->apLostToPk, 0); cout << endl << "Valid update" << endl; expHourCalc->updateAp(94500); parser->processLines(); doTest("currentAp after getting PKed", expHourCalc->currentAp, 94500); doTest("apGained after getting PKed", expHourCalc->apGained, 94500); doTest("lastApPacket after getting PKed", expHourCalc->lastApPacket, -500); doTest("apLostToPk after getting PKed", expHourCalc->apLostToPk, 500); doTest("Still need ap update", expHourCalc->needApUpdate, false); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); doTest("apLostToPk", expHourCalc->apLostToPk, 500); header("Double deaths"); appendFile("temp.txt","2013.06.27 17:08:23 : You have gained 3,421,093 XP from Lumiden. "); appendFile("temp.txt","2013.06.27 17:08:23 : You have gained 402 Abyss Points. "); appendFile("temp.txt","2013.06.27 17:08:23 : You can receive the weekly quest again at 9 in the morning on Wednesday. "); appendFile("temp.txt","2013.09.05 20:35:58 : You were killed by SteveForansi's attack."); parser->processLines(); expHourCalc->updateAp(93602); parser->processLines(); doTest("currentAp after getting PKed for second time", expHourCalc->currentAp, 93602); doTest("apGained after getting PKed for second time", expHourCalc->apGained, 93602); doTest("lastApPacket after getting PKed for second time", expHourCalc->lastApPacket, -1300); doTest("apLostToPk", expHourCalc->apLostToPk, 1800); doTest("Still need ap update", expHourCalc->needApUpdate, false); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); cout << endl << "Reject inputs that exceed currentAP + apLostToPk" << endl; appendFile("temp.txt","2013.09.05 20:35:58 : You were killed by V****a's attack."); parser->processLines(); expHourCalc->updateAp(95403); parser->processLines(); doTest("currentAp", expHourCalc->currentAp, 93602); doTest("apGained ", expHourCalc->apGained, 93602); doTest("lastApPacket", expHourCalc->lastApPacket, -1300); doTest("apLostToPk", expHourCalc->apLostToPk, 1800); doTest("Still need ap update", expHourCalc->needApUpdate, true); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, false); expHourCalc->updateAp(95402); parser->processLines(); cout << endl << "Allow manual updates up to currentAP + apLostToPk" << endl; doTest("currentAp", expHourCalc->currentAp, 95402); doTest("apGained ", expHourCalc->apGained, 95402); doTest("lastApPacket", expHourCalc->lastApPacket, 1800); doTest("apLostToPk", expHourCalc->apLostToPk, 0); doTest("Still need ap update", expHourCalc->needApUpdate, false); doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true); //================================================================================ header("AP not entered during startup"); expHourCalc->reset(); expHourCalc->level = 60; expHourCalc->currentExp = 50000000; expHourCalc->currentAp = -1; expHourCalc->apGained = 95000; expHourCalc->lastApPacket = 1234; appendFile("temp.txt","2013.06.27 19:04:58 : You were killed by Mrplatino's attack."); parser->processLines(); doTest("Still need ap update", expHourCalc->needApUpdate, false); doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false); cout << endl << "Attacked by player, finishing blow by monster, soul healing" << endl; appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. "); appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. "); parser->processLines(); doTest("Still need ap update", expHourCalc->needApUpdate, false); doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false); cout << endl << "Attacked by player, finishing blow by monster, manual exp update" << endl; appendFile("temp.txt","2013.06.27 23:03:19 : You have died. "); parser->processLines(); expHourCalc->updateExp(50000000); parser->processLines(); doTest("don't need exp update", expHourCalc->needExpUpdate, false); doTest("Still need ap update", expHourCalc->needApUpdate, false); doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, true); //================================================================================ header("Blood Marks and AP Relics"); expHourCalc->reset(); expHourCalc->currentAp = 10000; expHourCalc->apGained = 1000; appendFile("temp.txt","2013.07.23 12:32:19 : You have acquired [item:186000066;ver4;;;;]. "); appendFile("temp.txt","2013.07.23 12:32:19 : You have acquired 2 [item:162000120;ver4;;;;](s). "); parser->processLines(); doTest("currentAP after lesser icon", expHourCalc->currentAp, 10000); doTest("apGained after lesser icon", expHourCalc->apGained, 1000); doTest("relicAp after lesser icon", expHourCalc->relicAp, 315); appendFile("temp.txt","2013.07.22 17:19:53 : Quest updated: [Daily] Sweeping Away the Elyos "); appendFile("temp.txt","2013.07.22 17:19:54 : You have acquired 12 [item:186000236;ver4;;;;]s and stored them in your special cube. "); appendFile("temp.txt","2013.07.22 17:19:54 : You have gained 3,446,516 XP from Hrund. "); appendFile("temp.txt","2013.07.22 17:19:54 : You can receive the weekly quest again at 9 in the morning on Wednesday. "); appendFile("temp.txt","2013.07.22 17:19:54 : Quest complete: [Daily] Sweeping Away the Elyos "); parser->processLines(); doTest("relicAp after 12 blood mark", expHourCalc->relicAp, 6413); //================================================================================ header("NPC Sales"); //isNpcSales appendFile("temp.txt","2013.11.07 03:15:58 : Sales complete."); appendFile("temp.txt","2013.11.07 03:15:58 : You have earned 288 Kinah."); parser->processLines(); doTest("cashGained", expHourCalc->cashGained, 288); doTest("cashSpent", expHourCalc->cashSpent, 0); doTest("lastCashTransaction", expHourCalc->lastCashTransaction, 288); doTest("getNetCashFlow()", expHourCalc->getNetCashFlow(), 288); doTest("npcSales", expHourCalc->npcSales, 288); appendFile("temp.txt", "2013.09.03 22:39:32 : You sold the item. "); appendFile("temp.txt", "2013.09.03 22:39:32 : You have gained 376,068 Abyss Points. "); parser->processLines(); doTest("currentAp", expHourCalc->currentAp, 10000 + 376068); doTest("apGained", expHourCalc->apGained, 1000 + 376068); doTest("relicAp", expHourCalc->relicAp, 6413 - 376068); header("Not NPC Sales"); appendFile("temp.txt", "2013.11.05 13:04:54 : You have earned 11,550,000 Kinah."); parser->processLines(); doTest("cashGained", expHourCalc->cashGained, 11550000 + 288); doTest("cashSpent", expHourCalc->cashSpent, 0); doTest("lastCashTransaction", expHourCalc->lastCashTransaction, 11550000); doTest("getNetCashFlow()", expHourCalc->getNetCashFlow(), 11550288); doTest("npcSales", expHourCalc->npcSales, 288); appendFile("temp.txt", "2013.11.05 13:43:19 : Captain Anusa is under attack. "); appendFile("temp.txt", "2013.11.05 13:43:20 : You have gained 5,674 Abyss Points. "); appendFile("temp.txt", "2013.11.05 13:43:20 : Quest updated: [Service/Group] Unending Assault "); parser->processLines(); doTest("currentAp", expHourCalc->currentAp, 10000 + 376068 + 5674); doTest("apGained", expHourCalc->apGained, 1000 + 376068 + 5674); doTest("relicAp", expHourCalc->relicAp, 6413 - 376068); //================================================================================ header("Join Channel"); appendFile("temp.txt","2013.07.24 15:28:52 : You have joined the Poeta region channel. "); appendFile("temp.txt","2013.07.24 15:28:52 : You have joined the Poeta trade channel. "); appendFile("temp.txt","2013.07.24 15:28:52 : You have joined the LFG Channel. "); appendFile("temp.txt","2013.07.24 15:28:55 : You have joined the Assassin Channel. "); appendFile("temp.txt","2013.07.24 15:28:55 : You have joined the Ranger Channel. "); appendFile("temp.txt","2013.06.25 14:44:16 : You have joined Instance Server."); parser->processLines(); doTest("currentServer", expHourCalc->currentServer, INSTANCE_SERVER); doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false); //================================================================================ header("Do not recognize user chat as commands"); expHourCalc->reset(); expHourCalc->level = 43; expHourCalc->currentExp = 21016061; expHourCalc->lastExpPacket = 10000; expHourCalc->lastCashTransaction = 62351; appendFile("temp.txt","2013.07.24 15:24:51 : [3.LFG] [charname:Eikwel;1.0000 0.6941 0.6941]: blah blah blah : You received Soul Healing."); parser->processLines(); doTest("Soul healing from chat", expHourCalc->currentExp, 21016061); doTest("Soul healing from chat", expHourCalc->lastExpPacket, 10000); doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false); //================================================================================ printSummary(); delete(parser); remove("temp.txt"); getchar(); return 0; }
int main(int argc, char **argv) { cache_built_param param; cache_output_param output; output.hits = 0; output.misses = 0; output.evicts = 0; char *trace_file; FILE *input_file; char trace_op; unsigned long long int address; // hold for 64-bytes address int size; char c; while ((c = getopt(argc, argv, "s: E: b: t: hv")) != -1) { switch(c) { case 's': param.s = atoi(optarg); // transfer input string argument to integer break; case 'E': param.E = atoi(optarg); break; case 'b': param.b = atoi(optarg); break; case 't': trace_file = optarg; break; default: break; } } /* * check whether the input parameters are legal and complete */ if (param.s == 0 || param.E == 0 || param.b == 0 || trace_file == NULL) { printf("Miss required command line argument"); exit(1); } // create a cache according to the given parameters cache new_cache = create_cache(param.s, param.E, param.b); // open the input file to get operations input_file = fopen(trace_file, "r"); if (input_file != NULL) { /* * get the trace command from each line */ while(fscanf(input_file, " %c %llx,%d", &trace_op, &address, &size) == 3) { switch(trace_op) { case 'I': break; case 'S': printf("%c %llx %d\n", trace_op, address, size); output = simulated_cache(&new_cache, param, output, address); break; case 'L': printf("%c %llx %d\n", trace_op, address, size); output = simulated_cache(&new_cache, param, output, address); break; case 'M': printf("%c %llx %d\n", trace_op, address, size); output = simulated_cache(&new_cache, param, output, address); output = simulated_cache(&new_cache, param, output, address); break; default: break; } } printSummary(output.hits, output.misses, output.evicts); // print out the result free_cache(&new_cache, param.s, param.E, param.b); fclose(input_file); return 0; } }
int main(int argc, char **argv) { FILE *fp, *fp2; char testName[32] = "MPI_Rget", file1[64], file2[64]; int dblSize, proc, nprocs, npairs, partner; unsigned int i, j, k, size, localSize, NLOOP = NLOOP_MAX; unsigned int smin = MIN_P2P_SIZE, smed = MED_P2P_SIZE, smax = MAX_P2P_SIZE; double tScale = USEC, bwScale = MB_8; double tStart, timeMin, timeMinGlobal, overhead, threshold_lo, threshold_hi; double msgBytes, sizeBytes, localMax, UsedMem; double tElapsed[NREPS], tElapsedGlobal[NREPS]; double *A, *B; MPI_Win win; MPI_Status stat; MPI_Request req; // Initialize parallel environment MPI_Init(&argc, &argv); MPI_Comm_size( MPI_COMM_WORLD, &nprocs ); MPI_Comm_rank( MPI_COMM_WORLD, &proc ); // Test input parameters if( nprocs%2 != 0 && proc == 0 ) fatalError( "P2P test requires an even number of processors" ); // Check for user defined limits checkEnvP2P( proc, &NLOOP, &smin, &smed, &smax ); // Initialize local variables localMax = 0.0; npairs = nprocs/2; if( proc < npairs ) partner = proc + npairs; if( proc >= npairs ) partner = proc - npairs; UsedMem = (double)smax*(double)sizeof(double)*2.0; // Allocate and initialize arrays srand( SEED ); A = doubleVector( smax ); B = doubleVector( smax ); // Open output file and write header if( proc == 0 ){ // Check timer overhead in seconds timerTest( &overhead, &threshold_lo, &threshold_hi ); // Open output files and write headers sprintf( file1, "rget_time-np_%.4d.dat", nprocs ); sprintf( file2, "rget_bw-np_%.4d.dat", nprocs ); fp = fopen( file1, "a" ); fp2 = fopen( file2, "a" ); printHeaders( fp, fp2, testName, UsedMem, overhead, threshold_lo ); } // Get type size MPI_Type_size( MPI_DOUBLE, &dblSize ); // Set up a window for RMA MPI_Win_create( A, smax*dblSize, dblSize, MPI_INFO_NULL, MPI_COMM_WORLD, &win ); MPI_Win_lock_all( 0, win ); //================================================================ // Single loop with minimum size to verify that inner loop length // is long enough for the timings to be accurate //================================================================ // Warmup with a medium size message if( proc < npairs ){ MPI_Rget( B, smed, MPI_DOUBLE, partner, 0, smed, MPI_DOUBLE, win, &req ); MPI_Wait( &req, &stat ); MPI_Win_flush_all( win ); } // Test if current NLOOP is enough to capture fastest test cases MPI_Barrier( MPI_COMM_WORLD ); tStart = benchTimer(); if( proc < npairs ){ for(j = 0; j < NLOOP; j++){ MPI_Rget( B, smin, MPI_DOUBLE, partner, 0, smin, MPI_DOUBLE, win, &req ); MPI_Wait( &req, &stat ); MPI_Win_flush_all( win ); } } timeMin = benchTimer() - tStart; MPI_Reduce( &timeMin, &timeMinGlobal, 1, MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD ); if( proc == 0 ) resetInnerLoop( timeMinGlobal, threshold_lo, &NLOOP ); MPI_Bcast( &NLOOP, 1, MPI_INT, 0, MPI_COMM_WORLD ); //================================================================ // Execute test for each requested size //================================================================ for( size = smin; size <= smax; size = size*2 ){ // Warmup with a medium size message if( proc < npairs ){ MPI_Rget( B, smed, MPI_DOUBLE, partner, 0, smed, MPI_DOUBLE, win, &req ); MPI_Wait( &req, &stat ); MPI_Win_flush_all( win ); } // Repeat NREPS to collect statistics for(i = 0; i < NREPS; i++){ MPI_Barrier( MPI_COMM_WORLD ); tStart = benchTimer(); if( proc < npairs ){ for(j = 0; j < NLOOP; j++){ MPI_Rget( B, size, MPI_DOUBLE, partner, 0, size, MPI_DOUBLE, win, &req ); MPI_Wait( &req, &stat ); MPI_Win_flush_all( win ); } } tElapsed[i] = benchTimer() - tStart; } MPI_Reduce( tElapsed, tElapsedGlobal, NREPS, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD ); // Only task 0 needs to do the analysis of the collected data if( proc == 0 ){ // sizeBytes is size to write to file // msgBytes is actual data exchanged on the wire msgBytes = (double)size*(double)npairs*(double)dblSize; sizeBytes = (double)size*(double)dblSize; post_process( fp, fp2, threshold_hi, tElapsedGlobal, tScale, bwScale, size*dblSize, sizeBytes, msgBytes, &NLOOP, &localMax, &localSize ); } MPI_Bcast( &NLOOP, 1, MPI_INT, 0, MPI_COMM_WORLD ); } MPI_Win_unlock_all( win ); MPI_Win_free( &win ); MPI_Barrier( MPI_COMM_WORLD ); free( A ); free( B ); //================================================================ // Print completion message, free memory and exit //================================================================ if( proc == 0 ){ printSummary( fp2, testName, localMax, localSize ); fclose( fp2 ); fclose( fp ); } MPI_Finalize(); return 0; }
int main (int argc, char** argv) { double snp_mutation_rate = 0.001; double indel_mutation_rate = 0.0001; double het_rate = 0.5; double afs_alpha = 1; double indel_alpha = 3; double microsatellite_afs_alpha = 1; double microsatellite_len_alpha = 1.7; double microsatellite_mutation_rate = 0.0001; double mnp_ratio = 0.01; double tstv_ratio = 2.5; double deamination_ratio = 1.8; int microsatellite_min_length = 1; int indel_max = 1000; int ploidy = 1; int population_size = 1; int sample_id_max_digits = 1; int seed = time(NULL); string fastaFileName; string file_prefix = ""; string sample_prefix = ""; bool dry_run = false; int repeat_size_max = 20; bool uniform_indel_distribution = false; double p, lambda, shape, mu, sigma; string command_line = argv[0]; for (int i = 1; i < argc; ++i) { command_line += " "; command_line += argv[i]; } int c; while (true) { static struct option long_options[] = { /* These options set a flag. */ //{"verbose", no_argument, &verbose_flag, 1}, //{"brief", no_argument, &verbose_flag, 0}, {"help", no_argument, 0, 'h'}, {"snp-rate", required_argument, 0, 's'}, {"mnp-ratio", required_argument, 0, 'M'}, {"indel-rate", required_argument, 0, 'i'}, {"indel-alpha", required_argument, 0, 'z'}, {"indel-max", required_argument, 0, 'X'}, {"repeat-size-max", required_argument, 0, 'q'}, {"microsat-rate", required_argument, 0, 'm'}, {"microsat-afs-alpha", required_argument, 0, 't'}, {"microsat-len-alpha", required_argument, 0, 'j'}, {"microsat-min-len", required_argument, 0, 'l'}, {"afs-alpha", required_argument, 0, 'a'}, {"ploidy", required_argument, 0, 'p'}, {"population-size", required_argument, 0, 'n'}, {"file-prefix", required_argument, 0, 'P'}, {"sample-prefix", required_argument, 0, 'S'}, {"random-seed", required_argument, 0, 'g'}, {"dry-run", no_argument, 0, 'd'}, {"uniform-indels", no_argument, 0, 'U'}, {"ts-tv-ratio", required_argument, 0, 'T'}, {"deamination-ratio", required_argument, 0, 'D'}, {0, 0, 0, 0} }; /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "hdUa:z:s:i:q:p:n:M:X:t:m:P:S:g:l:j:T:", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case 'd': dry_run = true; break; case 'U': uniform_indel_distribution = true; break; case 'q': if (!convert(optarg, repeat_size_max)) { cerr << "could not read -q, --repeat-size-max" << endl; exit(1); } break; case 's': if (!convert(optarg, snp_mutation_rate)) { cerr << "could not read -s, --snp-rate" << endl; exit(1); } break; case 'i': if (!convert(optarg, indel_mutation_rate)) { cerr << "could not read -i, --indel-rate" << endl; exit(1); } break; case 'a': if (!convert(optarg, afs_alpha)) { cerr << "could not read -a, --afs-alpha" << endl; exit(1); } break; case 'z': if (!convert(optarg, indel_alpha)) { cerr << "could not read -z, --indel-alpha" << endl; exit(1); } break; case 'X': if (!convert(optarg, indel_max)) { cerr << "could not read -M, --indel-max" << endl; exit(1); } break; case 'M': if (!convert(optarg, mnp_ratio)) { cerr << "could not read -m, --mnp-ratio" << endl; exit(1); } break; case 'm': if (!convert(optarg, microsatellite_mutation_rate)) { cerr << "could not read -m, --microsat-rate" << endl; exit(1); } break; case 'T': if (!convert(optarg, tstv_ratio)) { cerr << "could not read -T, --ts-tv-ratio" << endl; exit(1); } break; case 't': if (!convert(optarg, microsatellite_afs_alpha)) { cerr << "could not read -m, --microsatellite-afs-alpha" << endl; exit(1); } break; case 'j': if (!convert(optarg, microsatellite_len_alpha)) { cerr << "could not read -m, --microsatellite-len-alpha" << endl; exit(1); } break; case 'l': if (!convert(optarg, microsatellite_min_length)) { cerr << "could not read -l, --microsat-min-len" << endl; exit(1); } break; case 'p': if (!convert(optarg, ploidy)) { cerr << "could not read -p, --ploidy" << endl; exit(1); } break; case 'P': file_prefix = optarg; break; case 'S': sample_prefix = optarg; break; case 'n': if (!convert(optarg, population_size)) { cerr << "could not read -n, --population-size" << endl; exit(1); } sample_id_max_digits = strlen(optarg); break; case 'g': if (!convert(optarg, seed)) { cerr << "could not read -g, --random-seed" << endl; exit(1); } break; case 'h': printSummary(); exit(0); break; case '?': /* getopt_long already printed an error message. */ printSummary(); exit(1); break; default: abort (); } } /* Print any remaining command line arguments (not options). */ if (optind < argc) { //cerr << "fasta file: " << argv[optind] << endl; fastaFileName = argv[optind]; } else { cerr << "please specify a fasta file" << endl; printSummary(); exit(1); } init_genrand(seed); // seed mt with current time //mt19937 eng(seed); int bpPerHaplotypeMean = 1000; double bpPerHaplotypeSigma = 200; normal_distribution<double> normal(mu, sigma); //lambda = 7.0; //poisson_distribution<int> poisson(lambda); //poisson(eng); string seqname; string sequence; // holds sequence so we can process it FastaReference fr; fr.open(fastaFileName); string bases = "ATGC"; vcf::VariantCallFile vcfFile; // write the VCF header stringstream headerss; headerss << "##fileformat=VCFv4.1" << endl << "##fileDate=" << dateStr() << endl << "##source=mutatrix population genome simulator" << endl << "##seed=" << seed << endl << "##reference=" << fastaFileName << endl << "##phasing=true" << endl << "##commandline=" << command_line << endl << "##INFO=<ID=AC,Number=A,Type=Integer,Description=\"Alternate allele count\">" << endl << "##INFO=<ID=TYPE,Number=A,Type=String,Description=\"Type of each allele (snp, ins, del, mnp, complex)\">" << endl << "##INFO=<ID=NS,Number=1,Type=Integer,Description=\"Number of samples at the site\">" << endl << "##INFO=<ID=NA,Number=1,Type=Integer,Description=\"Number of alternate alleles\">" << endl << "##INFO=<ID=LEN,Number=A,Type=Integer,Description=\"Length of each alternate allele\">" << endl << "##INFO=<ID=MICROSAT,Number=0,Type=Flag,Description=\"Generated at a sequence repeat loci\">" << endl << "##FORMAT=<ID=GT,Number=1,Type=String,Description=\"Genotype\">" << endl << "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT"; vector<string> samples; for (int i = 0; i < population_size; ++i) { stringstream sampless; sampless << sample_prefix << setfill('0') << setw(sample_id_max_digits) << i + 1; // one-based sample names samples.push_back(sampless.str()); headerss << "\t" << sampless.str(); } // and set up our VCF output file string header = headerss.str(); vcfFile.openForOutput(header); cout << vcfFile.header << endl; int copies = ploidy * population_size; map<string, vector<SampleFastaFile*> > sequencesByRefseq; if (!dry_run) { for (FastaIndex::iterator s = fr.index->begin(); s != fr.index->end(); ++s) { FastaIndexEntry& indexEntry = s->second; seqname = indexEntry.name; vector<SampleFastaFile*>& sequences = sequencesByRefseq[seqname]; for (int i = 0; i < population_size; ++i) { stringstream sname; sname << sample_prefix << setfill('0') << setw(sample_id_max_digits) << i + 1; string samplename = sname.str(); for (int j = 0; j < ploidy; ++j) { stringstream cname; cname << j; string chromname = cname.str(); string fullname = samplename + ":" + seqname + ":" + chromname; string filename = file_prefix + fullname + ".fa"; //sequences.push_back(SampleFastaFile(filename, seqname)); sequences.push_back(new SampleFastaFile(filename, seqname)); } } } } for (FastaIndex::iterator s = fr.index->begin(); s != fr.index->end(); ++s) { FastaIndexEntry& indexEntry = s->second; seqname = indexEntry.name; sequence = fr.getSequence(s->first); vector<SampleFastaFile*>& sequences = sequencesByRefseq[seqname]; //sequences.resize(copies); long int pos = 0; long int microsatellite_end_pos = 0; while (pos < sequence.size()) { //cout << pos + 1 << " microsat end pos " << microsatellite_end_pos << endl; string ref = sequence.substr(pos, 1); // by default, ref is just the current base // skip non-DNA sequence information if (!(ref == "A" || ref == "T" || ref == "C" || ref == "G")) { pos += ref.size(); for (vector<SampleFastaFile*>::iterator s = sequences.begin(); s != sequences.end(); ++s) { (*s)->write(ref); } continue; } vector<Allele> alleles; // establish if we are in a repeat // and what motif is being repeated, how many times int len = 1; // get reference repeats // if we have a repeat, adjust the mutation rate // using length and direction-dependent // formula from "Likelihood-Based Estimation of Microsatellite Mutation Rates" // http://www.genetics.org/cgi/content/full/164/2/781#T1 if (pos > microsatellite_end_pos) { map<string, int> repeats = repeatCounts(pos + 1, (const string&) sequence, repeat_size_max); string seq; int repeat_count = 0; // get the "biggest" repeat, the most likely ms allele at this site for (map<string, int>::iterator r = repeats.begin(); r != repeats.end(); ++r) { if (repeat_count < r->second) { repeat_count = r->second; seq = r->first; } } //cout << pos + 1 << " " << sequence.substr(pos + 1, seq.size() * repeat_count) << " ?= " << seq * repeat_count << endl; // guard ensures that we are in a pure repeat situoation, tandem-tandem repeats are not handled presently if (repeats.size() > 0 && sequence.substr(pos + 1, seq.size() * repeat_count) == seq * repeat_count) { int microsatellite_length = repeat_count * seq.size(); // record end of microsatellite so we don't generate more mutations until we pass it microsatellite_end_pos = pos + microsatellite_length - 1; if (microsatellite_length > microsatellite_min_length //&& genrand_real1() / copies // < microsatellite_mutation_rate * repeat_count) { && genrand_real1() > pow(1 - (microsatellite_mutation_rate * repeat_count), log(copies) * 2)) { // establish the relative rate of ins and del events /* long double repeatMutationDelProbability = microsatelliteDelProb(repeat_count); long double repeatMutationInsProbability = microsatelliteInsProb(repeat_count); long double indel_balance = 1; if (repeatMutationInsProbability > repeatMutationDelProbability) { indel_balance = repeatMutationInsProbability / repeatMutationDelProbability; } else { indel_balance = 1 - (repeatMutationInsProbability / repeatMutationDelProbability); } */ double indel_balance = 0.5; // how many alleles at the site? //int numalleles = min((int) floor(zetarandom(microsatellite_afs_alpha)), (int) ((double) repeat_count * indel_balance)); int numalleles = random_allele_frequency(repeat_count, microsatellite_afs_alpha); //cout << "repeat_count: " << repeat_count << " numalleles: " << numalleles << endl; map<int, bool> allele_lengths; // lengths of the alleles while (allele_lengths.size() < numalleles) { int allele_length; // TODO adjust length so that shorter events are more likely... if (genrand_real1() > indel_balance) { allele_length = -1 * min((int) floor(zetarandom(microsatellite_len_alpha)), repeat_count); } else { allele_length = min((int) floor(zetarandom(microsatellite_len_alpha)), repeat_count); } //cout << allele_length << endl; map<int, bool>::iterator f = allele_lengths.find(allele_length); if (f == allele_lengths.end()) { allele_lengths[allele_length] = true; } } // generate alleles for (map<int, bool>::iterator f = allele_lengths.begin(); f != allele_lengths.end(); ++f) { int allele_length = f->first; int c = abs(f->first); string alt = seq; for (int i = 1; i < c; ++i) alt += seq; if (allele_length > 0) { alleles.push_back(Allele(ref, ref + alt, "MICROSAT")); } else { alleles.push_back(Allele(ref + alt, ref, "MICROSAT")); } //cout << pos + 1 << " " << microsatellite_length << " " << alleles.back() << endl; } //cout << "alleles.size() == " << alleles.size() << endl; } } } // snp case if (genrand_real1() > pow(1 - snp_mutation_rate, log(max(copies, 2)) * 2)) { // make an alternate allele /* string alt = ref; while (alt == ref) { alt = string(1, bases.at(genrand_int32() % 4)); } */ string alt = ref; if (genrand_real1() > 1 / (1 + tstv_ratio)) { if (ref == "A") { alt = "G"; } else if (ref == "G") { alt = "A"; } else if (ref == "C") { alt = "T"; } else if (ref == "T") { alt = "C"; } } else { while (alt == ref || isTransition(ref, alt)) { alt = string(1, bases.at(genrand_int32() % 4)); } } if (genrand_real1() < mnp_ratio) { int i = 1; do { ref += sequence.substr(pos + i, 1); alt += sequence.substr(pos + i, 1); ++i; while (alt.at(alt.size() - 1) == ref.at(ref.size() - 1)) { alt.at(alt.size() - 1) = bases.at(genrand_int32() % 4); } } while (genrand_real1() < mnp_ratio); len = alt.size(); } alleles.push_back(Allele(ref, alt)); } // indel case if (genrand_real1() > pow(1 - indel_mutation_rate, log(max(copies, 2)) * 2)) { // how many bp? if (uniform_indel_distribution) { len = (int) floor(genrand_real1() * indel_max); } else { len = (int) floor(zetarandom(indel_alpha)); } // guard against out-of-sequence indels if (pos + len < sequence.size() && len <= indel_max) { if (genrand_int32() % 2 == 0) { // deletion alleles.push_back(Allele(sequence.substr(pos, 1 + len), sequence.substr(pos, 1))); } else { string alt = ref; // insertion? // insert some random de novo bases while (alt.length() < len + 1) { alt += string(1, bases.at(genrand_int32() % 4)); } alleles.push_back(Allele(ref, alt)); } } else { // fall through } } // no mutation generated if (alleles.empty()) { for (int i = 0; i < copies; ++i) { if (!dry_run) { sequences.at(i)->write(ref); } } pos += ref.size(); } else { // TODO randomly distribute all the alleles throughout the population // generate allele frequencies for each // fun times... string genotype; vector<bool> alts; random_shuffle(alleles.begin(), alleles.end()); vector<Allele*> population_alleles; list<Allele> present_alleles; // filtered for AFS > 0 in the sample // AFS simulation int remaining_copies = copies; while (remaining_copies > 0 && !alleles.empty()) { Allele allele = alleles.back(); alleles.pop_back(); int allele_freq = random_allele_frequency(remaining_copies, afs_alpha); if (allele_freq > 0) { present_alleles.push_back(allele); Allele* allelePtr = &present_alleles.back(); for (int i = 0; i < allele_freq; ++i) { population_alleles.push_back(allelePtr); } remaining_copies -= allele_freq; } } if (present_alleles.empty()) { for (int i = 0; i < copies; ++i) { if (!dry_run) { sequences.at(i)->write(ref); } } pos += ref.size(); continue; } reverse(present_alleles.begin(), present_alleles.end()); // establish the correct reference sequence and alternate allele set for (list<Allele>::iterator a = present_alleles.begin(); a != present_alleles.end(); ++a) { Allele& allele = *a; //cout << allele << endl; if (allele.ref.size() > ref.size()) { ref = allele.ref; } } // reference alleles take up the rest Allele reference_allele = Allele(ref, ref); for (int i = 0; i < remaining_copies; ++i) { population_alleles.push_back(&reference_allele); } vector<string> altstrs; // now the reference allele is the largest possible, adjust the alt allele strings to reflect this // if we have indels, add the base before, set the position back one for (list<Allele>::iterator a = present_alleles.begin(); a != present_alleles.end(); ++a) { Allele& allele = *a; string alleleStr = ref; if (allele.ref.size() == allele.alt.size()) { alleleStr.replace(0, allele.alt.size(), allele.alt); } else { alleleStr.replace(0, allele.ref.size(), allele.alt); } allele.ref = ref; allele.alt = alleleStr; altstrs.push_back(alleleStr); } assert(population_alleles.size() == copies); // shuffle the alleles around the population random_shuffle(population_alleles.begin(), population_alleles.end()); vcf::Variant var(vcfFile); var.sequenceName = seqname; var.position = pos + 1; var.quality = 99; var.id = "."; var.filter = "."; var.info["NS"].push_back(convert(population_size)); var.info["NA"].push_back(convert(present_alleles.size())); var.format.push_back("GT"); var.ref = ref; var.alt = altstrs; // debugging, uncomment to see sequence context //cout << sequence.substr(pos - 10, 10) << "*" << ref << "*" << sequence.substr(pos + 1, 9) << endl; map<string, int> alleleIndexes; alleleIndexes[convert(reference_allele)] = 0; // XXX should we handle this differently, by adding the reference allele to present_alleles? int i = 1; for (list<Allele>::iterator a = present_alleles.begin(); a != present_alleles.end(); ++a, ++i) { Allele& allele = *a; //cout << allele << " " << i << endl; alleleIndexes[convert(allele)] = i; //cout << allele << " " << i << endl; } //for (map<string, int>::iterator a = alleleIndexes.begin(); a != alleleIndexes.end(); ++a) { // cout << a->first << " = " << a->second << endl; //} int j = 0; for (vector<string>::iterator s = samples.begin(); s != samples.end(); ++s, ++j) { string& sample = *s; vector<string> genotype; // XXX hack, maybe this should get stored in another map for easier access? for (int i = 0; i < ploidy; ++i) { int l = (j * ploidy) + i; //cout << l << " " << population_alleles.at(l) << " " << alleleIndexes[convert(population_alleles.at(l))] << endl; genotype.push_back(convert(alleleIndexes[convert(*population_alleles.at(l))])); } var.samples[sample]["GT"].push_back(join(genotype, "|")); //cout << var.samples[sample]["GT"].front() << endl; } // XXX THIS IS BROKEN BECAUSE YOUR REFERENCE ALLELE CHANGES // LENGTH WITH DELETIONS. // // IT'S POSSIBLE TO GET COMPLEX ALLELES AT THE INTERSECTIONS // BETWEEN ONE ALLELIC VARIANT AND ANOTHER. THIS IS BROKEN! // // TO FIX--- BUILD HAPLOTYPES, THEN DISTRIBUTE THEM WITHIN THE POPULATION // // now write out our sequence data (FASTA files) for (int j = 0; j < population_size; ++j) { for (int i = 0; i < ploidy; ++i) { int l = (j * ploidy) + i; Allele* allele = population_alleles.at(l); if (!dry_run) { sequences.at(l)->write(allele->alt); } } } // tabulate allele frequency, and write some details to the VCF for (list<Allele>::iterator a = present_alleles.begin(); a != present_alleles.end(); ++a) { Allele& allele = *a; Allele* allelePtr = &*a; vector<string> genotypes; genotypes.resize(population_size); int allele_freq = 0; // obtain allele frequencies and output FASTA sequence data // for each simulated sample for (int j = 0; j < population_size; ++j) { for (int i = 0; i < ploidy; ++i) { int l = (j * ploidy) + i; if (population_alleles.at(l) == allelePtr) { ++allele_freq; } } } // set up the allele-specific INFO fields in the VCF record var.info["AC"].push_back(convert(allele_freq)); int delta = allele.alt.size() - allele.ref.size(); if (delta == 0) { if (allele.ref.size() == 1) { var.info["TYPE"].push_back("snp"); var.info["LEN"].push_back(convert(allele.ref.size())); } else { var.info["TYPE"].push_back("mnp");; var.info["LEN"].push_back(convert(allele.ref.size())); } } else if (delta > 0) { var.info["TYPE"].push_back("ins");; var.info["LEN"].push_back(convert(abs(delta))); } else { var.info["TYPE"].push_back("del");; var.info["LEN"].push_back(convert(abs(delta))); } if (!allele.type.empty()) { var.infoFlags[allele.type] = true; } } // write the VCF record to stdout cout << var << endl; int largest_ref = 1; // enforce one pos for (list<Allele>::iterator a = present_alleles.begin(); a != present_alleles.end(); ++a) { if (a->ref.size() > largest_ref) { largest_ref = a->ref.size(); } } pos += largest_ref; // step by the size of the last event } } } // close, clean up files for (map<string, vector<SampleFastaFile*> >::iterator s = sequencesByRefseq.begin(); s != sequencesByRefseq.end(); ++s) { vector<SampleFastaFile*>& files = s->second; for (vector<SampleFastaFile*>::iterator f = files.begin(); f != files.end(); ++f) { delete *f; } files.clear(); } return 0; }
int main (int argc, char** argv) { string command; string fastaFileName; string seqname; string longseqname; long long start; long long length; bool buildIndex = false; // flag to force index building bool printEntropy = false; // entropy printing bool readRegionsFromStdin = false; //bool printLength = false; string region; int c; while (true) { static struct option long_options[] = { /* These options set a flag. */ //{"verbose", no_argument, &verbose_flag, 1}, //{"brief", no_argument, &verbose_flag, 0}, {"help", no_argument, 0, 'h'}, {"index", no_argument, 0, 'i'}, //{"length", no_argument, &printLength, true}, {"entropy", no_argument, 0, 'e'}, {"region", required_argument, 0, 'r'}, {"stdin", no_argument, 0, 'c'}, {0, 0, 0, 0} }; /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "hcier:", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case 'e': printEntropy = true; break; case 'c': readRegionsFromStdin = true; break; case 'i': buildIndex = true; break; case 'r': region = optarg; break; case 'h': printSummary(); exit(0); break; case '?': /* getopt_long already printed an error message. */ printSummary(); exit(1); break; default: abort (); } } /* Print any remaining command line arguments (not options). */ if (optind < argc) { //cerr << "fasta file: " << argv[optind] << endl; fastaFileName = argv[optind]; } else { cerr << "please specify a fasta file" << endl; printSummary(); exit(1); } if (buildIndex) { FastaIndex* fai = new FastaIndex(); //cerr << "generating fasta index file for " << fastaFileName << endl; fai->indexReference(fastaFileName); fai->writeIndexFile((string) fastaFileName + fai->indexFileExtension()); } string sequence; // holds sequence so we can optionally process it FastaReference fr; fr.open(fastaFileName); if (region != "") { FastaRegion target(region); if (target.startPos == -1) { sequence = fr.getSequence(target.startSeq); } else { sequence = fr.getSubSequence(target.startSeq, target.startPos - 1, target.length()); } } if (readRegionsFromStdin) { string regionstr; while (getline(cin, regionstr)) { FastaRegion target(regionstr); if (target.startPos == -1) { cout << fr.getSequence(target.startSeq) << endl; } else { cout << fr.getSubSequence(target.startSeq, target.startPos - 1, target.length()) << endl; } } } else { if (sequence != "") { if (printEntropy) { if (sequence.size() > 0) { cout << shannon_H((char*) sequence.c_str(), sequence.size()) << endl; } else { cerr << "please specify a region or sequence for which to calculate the shannon entropy" << endl; } } else { // if no statistical processing is requested, just print the sequence cout << sequence << endl; } } } return 0; }
/*Main function to run the cache simulator *@return 0 if success, 1 if fail */ int main(int argc, char** argv) { int verbose = 0; // verbose flag int s; // Number of set index bits int E; // Number of lines per set int b; // Number of block bits char* trace; //the trace file name cache* Cache; char c; while ((c = getopt(argc, argv, "s:E:b:t:vh")) != -1){ switch(c){ case 's': s = atoi(optarg); break; case 'E': E = atoi(optarg); break; case 'b': b = atoi(optarg); break; case 't': trace = optarg; break; case 'v': verbose = 1; break; case 'h': printUsage(); exit(0); default: printUsage(); exit(1); } } if (s == 0 || E == 0 || b == 0 || trace == NULL){ puts("Missing arguments"); printUsage(); return 1; } //Create the cache Cache = buildCache(s, E, b); //Read from the trace memAddr address; char act; int byteSize; FILE * traceFile = fopen(trace, "r"); //initilize cache tracker cacheParam param; param.s = s; param.b= b; param.E = E; param.S = 1 << s; param.B = 1 << b; param.hit =0; param.miss = 0; param.evict = 0; //Usage int state, state1, state2; if (traceFile != NULL) { while (fscanf(traceFile, " %c %llx,%d", &act, &address, &byteSize) == 3){ switch(act){ case 'I': break; case 'L': param = rSim(Cache, param, address, &state); if (verbose == 1) { printf("%c %llx,%d", act, address, byteSize); printState(state); printf("\n"); } break; case 'S': param = rSim(Cache, param, address, &state); if (verbose == 1) { printf("%c %llx,%d", act, address, byteSize); printState(state); printf("\n"); } break; case 'M': param = rSim(Cache, param, address, &state1); param = rSim(Cache, param, address, &state2); if (verbose == 1) { printf("%c %llx,%d", act, address, byteSize); printState(state1); printState(state2); printf("\n"); } break; default: break; } } } printSummary(param.hit, param.miss, param.evict); return 0; }