Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 /// \file scavenger/src/ParserChemReaction.cc << 26 /// \file ParserChemReaction.cc 27 /// \brief Implementation of the scavenger::Pa << 27 /// \brief Implementation of the ParserChemReaction class 28 28 29 #include "ParserChemReaction.hh" 29 #include "ParserChemReaction.hh" 30 << 31 #include "G4SystemOfUnits.hh" 30 #include "G4SystemOfUnits.hh" 32 << 33 #include <fstream> 31 #include <fstream> 34 32 35 namespace scavenger 33 namespace scavenger 36 { 34 { 37 35 38 //....oooOO0OOooo........oooOO0OOooo........oo 36 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 39 37 40 void ParserChemReaction::ReplaceString(G4Strin << 38 void ParserChemReaction::ReplaceString(G4String &aString, const G4String &from, 41 { << 39 const G4String &to) { 42 if (G4StrUtil::contains(aString, from)) { 40 if (G4StrUtil::contains(aString, from)) { 43 size_t startPosition = 0; 41 size_t startPosition = 0; 44 while ((startPosition = aString.find(from, << 42 while ((startPosition = aString.find(from, startPosition)) >> 43 != std::string::npos) { 45 aString.replace(startPosition, from.leng 44 aString.replace(startPosition, from.length(), to); 46 startPosition += to.length(); 45 startPosition += to.length(); 47 } 46 } 48 } 47 } 49 } 48 } 50 49 51 //....oooOO0OOooo........oooOO0OOooo........oo 50 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 52 51 53 void ParserChemReaction::ImplementReaction(con << 52 void ParserChemReaction::ImplementReaction(const G4String &reactant1, 54 con << 53 const G4String &reactant2, 55 con << 54 const std::vector<G4String> &product, 56 { << 55 const G4double &reactionRate, >> 56 const G4String &type) { 57 if (type == "I") { 57 if (type == "I") { 58 fListReactant1[0].push_back(reactant1); 58 fListReactant1[0].push_back(reactant1); 59 fListReactant2[0].push_back(reactant2); 59 fListReactant2[0].push_back(reactant2); 60 fListProduct[0].push_back(product); 60 fListProduct[0].push_back(product); 61 fListRate[0].push_back(reactionRate); 61 fListRate[0].push_back(reactionRate); 62 } << 62 } else if (type == "II") { 63 else if (type == "II") { << 64 fListReactant1[1].push_back(reactant1); 63 fListReactant1[1].push_back(reactant1); 65 fListReactant2[1].push_back(reactant2); 64 fListReactant2[1].push_back(reactant2); 66 fListProduct[1].push_back(product); 65 fListProduct[1].push_back(product); 67 fListRate[1].push_back(reactionRate); 66 fListRate[1].push_back(reactionRate); 68 } << 67 } else if (type == "III") { 69 else if (type == "III") { << 70 fListReactant1[2].push_back(reactant1); 68 fListReactant1[2].push_back(reactant1); 71 fListReactant2[2].push_back(reactant2); 69 fListReactant2[2].push_back(reactant2); 72 fListProduct[2].push_back(product); 70 fListProduct[2].push_back(product); 73 fListRate[2].push_back(reactionRate); 71 fListRate[2].push_back(reactionRate); 74 } << 72 } else if (type == "IV") { 75 else if (type == "IV") { << 76 fListReactant1[3].push_back(reactant1); 73 fListReactant1[3].push_back(reactant1); 77 fListReactant2[3].push_back(reactant2); 74 fListReactant2[3].push_back(reactant2); 78 fListProduct[3].push_back(product); 75 fListProduct[3].push_back(product); 79 fListRate[3].push_back(reactionRate); 76 fListRate[3].push_back(reactionRate); 80 } << 77 } else if (type == "VI") { 81 else if (type == "VI") { << 82 fListReactant1[4].push_back(reactant1); 78 fListReactant1[4].push_back(reactant1); 83 fListReactant2[4].push_back(reactant2); 79 fListReactant2[4].push_back(reactant2); 84 fListProduct[4].push_back(product); 80 fListProduct[4].push_back(product); 85 fListRate[4].push_back(reactionRate); 81 fListRate[4].push_back(reactionRate); 86 } 82 } 87 } 83 } 88 84 89 //....oooOO0OOooo........oooOO0OOooo........oo 85 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 90 86 91 void ParserChemReaction::ReadReaction(const G4 << 87 void ParserChemReaction::ReadReaction(const G4String &reactionString, 92 std::vec << 88 std::vector<G4String> &reactant, 93 std::vec << 89 std::vector<G4String> &product, 94 { << 90 G4double &reactionRate) { 95 reactant.clear(); 91 reactant.clear(); 96 product.clear(); 92 product.clear(); 97 93 98 G4bool readReaction = true; 94 G4bool readReaction = true; 99 G4bool readReactant = true; 95 G4bool readReactant = true; 100 G4bool readProduct = false; 96 G4bool readProduct = false; 101 G4bool readRate = false; 97 G4bool readRate = false; 102 98 103 std::stringstream aStream; 99 std::stringstream aStream; 104 aStream << reactionString; 100 aStream << reactionString; 105 101 106 while (!aStream.eof() && readReaction) { 102 while (!aStream.eof() && readReaction) { 107 G4String aString; 103 G4String aString; 108 aStream >> aString; 104 aStream >> aString; 109 105 110 if (G4StrUtil::contains(aString, "#")) { << 106 if (G4StrUtil::contains(aString,"#")) { 111 readReaction = false; 107 readReaction = false; 112 } << 108 } else if (readReactant) { 113 else if (readReactant) { << 114 if (aString == G4String("->")) { 109 if (aString == G4String("->")) { 115 readReactant = false; 110 readReactant = false; 116 readProduct = true; 111 readProduct = true; 117 } << 112 } else if (aString != G4String("+")) { 118 else if (aString != G4String("+")) { << 119 ReplaceString(aString, G4String("+"), 113 ReplaceString(aString, G4String("+"), G4String("p")); 120 ReplaceString(aString, G4String("-"), 114 ReplaceString(aString, G4String("-"), G4String("m")); 121 115 122 if (reactant.size() < 2) { 116 if (reactant.size() < 2) { 123 reactant.push_back(aString); 117 reactant.push_back(aString); 124 } 118 } 125 } 119 } 126 } << 120 } else if (readProduct) { 127 else if (readProduct) { << 128 if (aString == G4String(",")) { 121 if (aString == G4String(",")) { 129 readProduct = false; 122 readProduct = false; 130 readRate = true; 123 readRate = true; 131 } << 124 } else if (aString != G4String("+") && !G4StrUtil::contains(aString,"[") 132 else if (aString != G4String("+") && !G4 << 125 && !G4StrUtil::contains(aString,"]")) { 133 && !G4StrUtil::contains(aString << 134 { << 135 ReplaceString(aString, G4String("+"), 126 ReplaceString(aString, G4String("+"), G4String("p")); 136 ReplaceString(aString, G4String("-"), 127 ReplaceString(aString, G4String("-"), G4String("m")); 137 product.push_back(aString); 128 product.push_back(aString); 138 } 129 } 139 } << 130 } else if (readRate) { 140 else if (readRate) { << 141 std::stringstream aStreamTmp; 131 std::stringstream aStreamTmp; 142 aStreamTmp << aString; 132 aStreamTmp << aString; 143 aStreamTmp >> reactionRate; 133 aStreamTmp >> reactionRate; 144 134 145 if (reactant.size() == 1) { 135 if (reactant.size() == 1) { 146 // For first-order reactions 136 // For first-order reactions 147 reactionRate *= (1 * 1 / s); 137 reactionRate *= (1 * 1 / s); 148 } << 138 } else { 149 else { << 150 reactionRate *= (1e-3 * m3 / (mole * s 139 reactionRate *= (1e-3 * m3 / (mole * s)); 151 } 140 } 152 141 153 readRate = false; 142 readRate = false; 154 readReaction = false; 143 readReaction = false; 155 } 144 } 156 } 145 } 157 146 158 // For first-order reactions 147 // For first-order reactions 159 if (reactant.size() == 1) { 148 if (reactant.size() == 1) { 160 reactant.emplace_back("NoneM"); 149 reactant.emplace_back("NoneM"); 161 } 150 } 162 } 151 } 163 152 164 //....oooOO0OOooo........oooOO0OOooo........oo 153 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 165 154 166 G4double ParserChemReaction::GetScavengerConce << 155 G4double ParserChemReaction::GetScavengerConcentration(const G4String &name) { 167 { << 168 G4double concentration = -1.; 156 G4double concentration = -1.; 169 157 170 std::map<G4String, G4double>::iterator it; 158 std::map<G4String, G4double>::iterator it; 171 it = fReservoirConcentrationMap.find(name); 159 it = fReservoirConcentrationMap.find(name); 172 160 173 if (it != fReservoirConcentrationMap.end()) 161 if (it != fReservoirConcentrationMap.end()) { 174 concentration = it->second; 162 concentration = it->second; 175 } << 163 } else { 176 else { << 177 G4ExceptionDescription exception; 164 G4ExceptionDescription exception; 178 exception << "Scavenger is not defined: " 165 exception << "Scavenger is not defined: " 179 << "reaction will not be registe 166 << "reaction will not be registered!"; 180 G4Exception("ParserChemReaction::GetScaven << 167 G4Exception("ParserChemReaction::GetScavengerConcentration", "parchem01", 181 exception); << 168 JustWarning, exception); 182 } 169 } 183 170 184 return concentration; 171 return concentration; 185 } 172 } 186 173 187 //....oooOO0OOooo........oooOO0OOooo........oo 174 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 188 175 189 void ParserChemReaction::ReadReservoir(const G << 176 void ParserChemReaction::ReadReservoir(const G4String &reservoirString) { 190 { << 191 G4double concentration = 0.; 177 G4double concentration = 0.; 192 G4String name = ""; 178 G4String name = ""; 193 179 194 G4bool readScavenger = true; 180 G4bool readScavenger = true; 195 G4bool readName = false; 181 G4bool readName = false; 196 G4bool readConcentration = false; 182 G4bool readConcentration = false; 197 183 198 std::stringstream aStream; 184 std::stringstream aStream; 199 aStream << reservoirString; 185 aStream << reservoirString; 200 186 201 while (!aStream.eof() && readScavenger) { 187 while (!aStream.eof() && readScavenger) { 202 G4String aString; 188 G4String aString; 203 aStream >> aString; 189 aStream >> aString; 204 190 205 if (G4StrUtil::contains(aString, "#")) { << 191 if (G4StrUtil::contains(aString,"#")) { 206 readScavenger = false; 192 readScavenger = false; 207 } << 193 } else if (aString == G4String("scavenger:")) { 208 else if (aString == G4String("scavenger:") << 209 readName = true; 194 readName = true; 210 } << 195 } else if (readName) { 211 else if (readName) { << 212 name = G4String(aString); 196 name = G4String(aString); 213 ReplaceString(name, G4String("+"), G4Str 197 ReplaceString(name, G4String("+"), G4String("p")); 214 ReplaceString(name, G4String("-"), G4Str 198 ReplaceString(name, G4String("-"), G4String("m")); 215 199 216 readName = false; 200 readName = false; 217 readConcentration = true; 201 readConcentration = true; 218 } << 202 } else if (readConcentration) { 219 else if (readConcentration) { << 220 std::stringstream aStreamTmp; 203 std::stringstream aStreamTmp; 221 aStreamTmp << aString; 204 aStreamTmp << aString; 222 aStreamTmp >> concentration; 205 aStreamTmp >> concentration; 223 concentration *= (mole / (1e-3 * m3)); 206 concentration *= (mole / (1e-3 * m3)); 224 readConcentration = false; 207 readConcentration = false; 225 readScavenger = false; 208 readScavenger = false; 226 } 209 } 227 } 210 } 228 211 229 if (concentration > 0.) { 212 if (concentration > 0.) { 230 if (fReservoirConcentrationMap.count(name) 213 if (fReservoirConcentrationMap.count(name) < 1) { 231 fReservoirConcentrationMap[name] = conce 214 fReservoirConcentrationMap[name] = concentration; 232 } << 215 } else { 233 else { << 234 G4ExceptionDescription exception; 216 G4ExceptionDescription exception; 235 exception << "Scavenger already defined 217 exception << "Scavenger already defined previously:\n" 236 << "scavenger will not be regi 218 << "scavenger will not be registered!"; 237 G4Exception("ParserChemReaction::ReadRes << 219 G4Exception("ParserChemReaction::ReadReservoir", "parchem02", >> 220 JustWarning, exception); 238 } 221 } 239 } << 222 } else { 240 else { << 241 G4ExceptionDescription exception; 223 G4ExceptionDescription exception; 242 exception << "Null or negative scavenger c 224 exception << "Null or negative scavenger concentration:\n" 243 << "scavenger will not be regist 225 << "scavenger will not be registered!"; 244 G4Exception("ParserChemReaction::ReadReser << 226 G4Exception("ParserChemReaction::ReadReservoir", "parchem03", >> 227 JustWarning, exception); 245 } 228 } 246 } 229 } 247 230 248 //....oooOO0OOooo........oooOO0OOooo........oo 231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 249 232 250 void ParserChemReaction::AddReaction(const G4S << 233 void ParserChemReaction::AddReaction(const G4String &reactionString, 251 { << 234 const G4String &type) { 252 std::vector<G4String> reactant; 235 std::vector<G4String> reactant; 253 std::vector<G4String> product; 236 std::vector<G4String> product; 254 G4double reactionRate = -1; 237 G4double reactionRate = -1; 255 238 256 G4bool reservoir = false; 239 G4bool reservoir = false; 257 240 258 if (type == "VI") { 241 if (type == "VI") { 259 reservoir = true; 242 reservoir = true; 260 } 243 } 261 244 262 ReadReaction(reactionString, reactant, produ 245 ReadReaction(reactionString, reactant, product, reactionRate); 263 246 264 if (!reactant.empty() && (reactionRate <= 0) 247 if (!reactant.empty() && (reactionRate <= 0)) { 265 G4ExceptionDescription exception; 248 G4ExceptionDescription exception; 266 exception << "Null or negative reaction ra 249 exception << "Null or negative reaction rate: " 267 << "reaction will not be registe 250 << "reaction will not be registered!"; 268 G4Exception("ParserChemReaction::AddReacti << 251 G4Exception("ParserChemReaction::AddReaction", "parchem04", >> 252 JustWarning, exception); 269 return; 253 return; 270 } 254 } 271 255 272 G4double concentration; 256 G4double concentration; 273 257 274 if (reservoir && (reactant.size() >= 2)) { 258 if (reservoir && (reactant.size() >= 2)) { 275 if (G4StrUtil::contains(reactant[0], "[") << 259 if (G4StrUtil::contains(reactant[0],"[") && G4StrUtil::contains(reactant[0],"]")) { 276 ReplaceString(reactant[0], G4String("[") 260 ReplaceString(reactant[0], G4String("["), G4String("")); 277 ReplaceString(reactant[0], G4String("]") 261 ReplaceString(reactant[0], G4String("]"), G4String("")); 278 262 279 concentration = GetScavengerConcentratio 263 concentration = GetScavengerConcentration(reactant[0]); 280 264 281 if (concentration != -1) { 265 if (concentration != -1) { 282 reactionRate *= concentration; 266 reactionRate *= concentration; 283 reactant[0].append("(B)"); 267 reactant[0].append("(B)"); 284 ImplementReaction(reactant[1], reactan << 268 ImplementReaction(reactant[1], reactant[0], product, >> 269 reactionRate, type); 285 } 270 } 286 } << 271 } else if (G4StrUtil::contains(reactant[1],"[") && G4StrUtil::contains(reactant[1],"]")) { 287 else if (G4StrUtil::contains(reactant[1], << 288 ReplaceString(reactant[1], G4String("[") 272 ReplaceString(reactant[1], G4String("["), G4String("")); 289 ReplaceString(reactant[1], G4String("]") 273 ReplaceString(reactant[1], G4String("]"), G4String("")); 290 274 291 concentration = GetScavengerConcentratio 275 concentration = GetScavengerConcentration(reactant[1]); 292 276 293 if (concentration != -1) { 277 if (concentration != -1) { 294 reactionRate *= concentration; 278 reactionRate *= concentration; 295 reactant[1].append("(B)"); 279 reactant[1].append("(B)"); 296 ImplementReaction(reactant[0], reactan << 280 ImplementReaction(reactant[0], reactant[1], product, >> 281 reactionRate, type); 297 } 282 } 298 } << 283 } else if (reactant[1] == "NoneM") { 299 else if (reactant[1] == "NoneM") { << 300 // First-order reaction 284 // First-order reaction 301 ImplementReaction(reactant[0], reactant[ 285 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type); 302 } << 286 } else { 303 else { << 304 G4ExceptionDescription exception; 287 G4ExceptionDescription exception; 305 exception << "Missing or unsuitable squa 288 exception << "Missing or unsuitable square brackets:\n" 306 << "reaction will not be regis 289 << "reaction will not be registered.\n" 307 << "Verify the writing of chem 290 << "Verify the writing of chemical reactions!"; 308 G4Exception("ParserChemReaction::AddReac << 291 G4Exception("ParserChemReaction::AddReaction", "parchem05", >> 292 JustWarning, exception); 309 } 293 } 310 } << 294 } else if (reactant.size() >= 2) { 311 else if (reactant.size() >= 2) { << 295 if (!G4StrUtil::contains(reactant[0],"[") && !G4StrUtil::contains(reactant[0],"]") 312 if (!G4StrUtil::contains(reactant[0], "[") << 296 && !G4StrUtil::contains(reactant[1],"[") && !G4StrUtil::contains(reactant[1],"]") 313 && !G4StrUtil::contains(reactant[1], " << 297 && (reactant[1] != "NoneM")) { 314 && (reactant[1] != "NoneM")) << 315 { << 316 ImplementReaction(reactant[0], reactant[ 298 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type); 317 } << 299 } else if (reactant[1] == "NoneM") { 318 else if (reactant[1] == "NoneM") { << 319 G4ExceptionDescription exception; 300 G4ExceptionDescription exception; 320 exception << "Unsuitable reaction type: 301 exception << "Unsuitable reaction type: " 321 << "reaction will not be regis 302 << "reaction will not be registered.\n" 322 << "For first-order reaction, 303 << "For first-order reaction, use reaction type 6."; 323 G4Exception("ParserChemReaction::AddReac << 304 G4Exception("ParserChemReaction::AddReaction", "parchem06", 324 } << 305 JustWarning, exception); 325 else { << 306 } else { 326 G4ExceptionDescription exception; 307 G4ExceptionDescription exception; 327 exception << "Unsuitable square brackets 308 exception << "Unsuitable square brackets: " 328 << "reaction will not be regis 309 << "reaction will not be registered.\n" 329 << "Verify the writing of chem 310 << "Verify the writing of chemical reactions!"; 330 G4Exception("ParserChemReaction::AddReac << 311 G4Exception("ParserChemReaction::AddReaction", "parchem07", >> 312 JustWarning, exception); 331 } 313 } 332 } 314 } 333 } 315 } 334 316 335 //....oooOO0OOooo........oooOO0OOooo........oo 317 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 336 318 337 void ParserChemReaction::ReadReactionFile(cons << 319 void ParserChemReaction::ReadReactionFile(const G4String &fileName) { 338 { << 339 G4String line; 320 G4String line; 340 std::ifstream myFile(fileName); 321 std::ifstream myFile(fileName); 341 322 342 if (myFile.is_open()) { 323 if (myFile.is_open()) { 343 while (getline(myFile, line)) { 324 while (getline(myFile, line)) { 344 if (G4StrUtil::contains(line, "type_1")) << 325 if (G4StrUtil::contains(line,"type_1")) { 345 AddReaction(line, "I"); 326 AddReaction(line, "I"); 346 } << 327 } else if (G4StrUtil::contains(line,"type_2")) { 347 else if (G4StrUtil::contains(line, "type << 348 AddReaction(line, "II"); 328 AddReaction(line, "II"); 349 } << 329 } else if (G4StrUtil::contains(line,"type_3")) { 350 else if (G4StrUtil::contains(line, "type << 351 AddReaction(line, "III"); 330 AddReaction(line, "III"); 352 } << 331 } else if (G4StrUtil::contains(line,"type_4")) { 353 else if (G4StrUtil::contains(line, "type << 354 AddReaction(line, "IV"); 332 AddReaction(line, "IV"); 355 } << 333 } else if (G4StrUtil::contains(line,"type_6")) { 356 else if (G4StrUtil::contains(line, "type << 357 AddReaction(line, "VI"); 334 AddReaction(line, "VI"); 358 } << 335 } else if (G4StrUtil::contains(line,"scavenger:")) { 359 else if (G4StrUtil::contains(line, "scav << 360 ReadReservoir(line); 336 ReadReservoir(line); 361 } << 337 } else if (!G4StrUtil::contains(line,"#") && !line.empty()) { 362 else if (!G4StrUtil::contains(line, "#") << 363 G4ExceptionDescription exception; 338 G4ExceptionDescription exception; 364 exception << "Unknown declaration: " 339 exception << "Unknown declaration: " 365 << "reaction or scavenger wi 340 << "reaction or scavenger will not be registered.\n" 366 << "Verify the writing of ch 341 << "Verify the writing of chemical reactions or scavengers!"; 367 G4Exception("ParserChemReaction::ReadR << 342 G4Exception("ParserChemReaction::ReadReactionFile", "parchem08", >> 343 JustWarning, exception); 368 } 344 } 369 } 345 } 370 346 371 myFile.close(); 347 myFile.close(); 372 } << 348 } else { 373 else { << 374 G4ExceptionDescription exception; 349 G4ExceptionDescription exception; 375 exception << "Chemical reaction file not f 350 exception << "Chemical reaction file not found."; 376 G4Exception("ParserChemReaction::ReadReact << 351 G4Exception("ParserChemReaction::ReadReactionFile", "parchem09", >> 352 JustWarning, exception); 377 } 353 } 378 } 354 } 379 355 380 //....oooOO0OOooo........oooOO0OOooo........oo 356 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 381 357 382 } // namespace scavenger << 358 }