// Sc46SourceGen.cc // Contact person: David Auty (auty@ualberta.ca) // See Sc46SourceGen.hh for more details //———————————————————————// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace RAT { Sc46SourceGen::Sc46SourceGen() : fTimeGenName("poisson"),fPosGenName("point"), fDecayStr("46Sc"),fSourceName("TaggedSource_scintillator_phys") { DecayChain_Gen::SetState(fDecayStr + ":" + fPosGenName + ":" + fTimeGenName); // The sampler volume is hard-coded for this source. // In order to allow for the point generator we also want to store locally this volume // so one can compute local coordinates Log::Assert( Detector::FindPhysicalVolume(fSourceName) != NULL, "Sc46SourceGen: Did not find physical volume '" + fSourceName + "'. Please load the Tagged source geometry."); DecayChain_Gen::SetPosState(fSourceName); // Get all of the data required from the databases here DBLinkPtr sourceTable = DB::Get()->GetLink("GEO","TaggedSource"); // The geometry is built such that the position of the events should occur at // 'position', as set in TaggedSource.geo. Try to find it, and fail if not // found (geometry should not have been built without it, but it doesn't hurt // to check!). This position is the centre of the scintillator button. try{ fPos = sourceTable->GetDArray("position"); } catch(DBNotFoundError &e){ Log::Die("Sc46SourceGen::SetState error: Could not find position in TaggedSource.geo.\n"); } try{ fLCN = sourceTable->GetI("lcn"); } catch(DBNotFoundError &e){ Log::Die("Sc46SourceGen::SetState error: Could not find source LCN.\n"); } // Get the reference activity and date for the source (ie. the measured // activity on a particular date). If a date cannot be found, then default to // the date in DATE.ratdb. This implies the source activity will be equal to // that in TaggedSource.geo. try{ fRefActivity = sourceTable->GetD("ref_activity"); } catch(DBNotFoundError &e){ Log::Die("Sc46SourceGen::SetEvRate error: Could not find the reference activity in TaggedSource.geo.\n"); } try{ fRefDate = sourceTable->GetS("ref_date"); } catch(DBNotFoundError &e){ warn << "Sc46SourceGen::SetEvRate warning: Could not find the reference date for the source activity in TaggedSource.geo, so setting it equal to the run date in DATE.ratdb.\n"; // We'll do that setting below... fRefDate = ""; } //halflife hardcoded as not in data base yet (I couldn't find it) fHalfLife.push_back(83.79*3600*24); // Set the position state std::stringstream posStateStr; posStateStr << fPos.at(0) << " " << fPos.at(1) << " " << fPos.at(2); fPosStateStr = posStateStr.str(); DecayChain_Gen::SetPosState(fPosStateStr); // Calculate the event rate based on the run and reference dates and set the // activity for the generator. SetEvRate(); fTimeStateStr = GetEvRate(); DecayChain_Gen::SetTimeState(fTimeStateStr); } void Sc46SourceGen::SetState(G4String state) { if (state != "") { warn << "Warning: parameter '" << state << "' given for /generator/add sc46source has no effect.\n"; } } void Sc46SourceGen::SetPosState(G4String /*state*/) { warn << "Warning: /generator/set/pos has no effect for the sc46source generator.\n"; } void Sc46SourceGen::SetEvRate() { // The event rate is determined using the reference date and activity in // TaggedSource.geo and the run start date set in DATE.ratdb. // Grab the date of the run from DATE.ratdb and set its universal time. Use // the EventTime class to handle the universal time conversion. fEvTime.LoadDB(); // Now take the string that represents the reference data for the calibration // source and separate out the day, month, year, hour, minute and second // (in that order). The string is in the form DD MMM/MM YYYY HH:MM:SS, where // MMM is a 3 character name for the month or MM is an integer for the month if(fRefDate.compare("") != 0){ // In this case, the date was defaulted. std::vector dateInfo; std::istringstream ssrefDate(fRefDate); std::string elem; while(!ssrefDate.eof()){ ssrefDate >> elem; std::istringstream sselem(elem); std::string el; while(getline(sselem,el,':')){ if(dateInfo.size() == 1){ int monthTemp = GetMonthInt(el); if(monthTemp <= 12 && monthTemp > 0) dateInfo.push_back(monthTemp); else Log::Die("Sc46SourceGen::SetEvRate error: Month in reference date is incorrectly set.\n"); continue; } dateInfo.push_back(to_int(el)); } } Log::Assert(dateInfo.size() == 6, "Sc46SourceGen::SetEvRate error: Reference date for the calibration source is not in the correct format. Should be YYYY MMM DD HH:MM:SS. MMM is the first 3 letters of the month name.\n"); // Convert the reference date into a Universal Time. int UTday, UTsec; double UTnsec; int seconds = 3600*dateInfo.at(3)+60*dateInfo.at(4)+dateInfo.at(5); UTday = fEvTime.GetUTDay(dateInfo.at(2),dateInfo.at(1),dateInfo.at(0), seconds,0.0,UTday,UTsec,UTnsec); fEvTime.SetUT(UTday,UTsec,UTnsec); } else // Set the reference date to the run date (either ref_date does not exist // in database, or it was set to "" in the macro). fEvTime.SetUT(fEvTime.GetStartUTDays(), fEvTime.GetStartUTSecs(), fEvTime.GetStartUTNsecs()); // Calculate the time difference, in seconds, between the reference date and // the run start date. If the start date is earlier than the reference, an // error is thrown. double timeDiff = 86400.*(fEvTime.GetStartUTDays()-fEvTime.GetUTDays())+ 1.*(fEvTime.GetStartUTSecs()-fEvTime.GetUTSecs()); Log::Assert(timeDiff >= 0., "Sc46SourceGen::SetEvRate error: Reference date for the calibration source is later than the run date! Check the run date is set correctly in DATE.ratdb.\n"); // Calculate the activity of the source on the date of the run. Assume it is // constant over the run (which is a fair assumption, given the 84d half-life). //fActivity = fRefActivity*exp(-log(2.)*timeDiff/fHalfLife.at(0)); //add by hand at the moment fActivity = fRefActivity*exp(-log(2.)*timeDiff/fHalfLife.at(0)); std::stringstream ssRate; ssRate << fActivity; G4String sRate = ssRate.str(); detail << "Sc46SourceGen: Setting source activity to " << fActivity << " Bq based on a reference activity of " << fRefActivity << " Bq on " << fRefDate << ".\n"; fEvRate = sRate; } void Sc46SourceGen::BuildMonthMap() { // Build a map of name strings for the months to integers. Allow for various // 'spellings' of the months fMonth.insert(std::pair< std::string, int >("Jan",1)); fMonth.insert(std::pair< std::string, int >("jan",1)); fMonth.insert(std::pair< std::string, int >("January",1)); fMonth.insert(std::pair< std::string, int >("january",1)); fMonth.insert(std::pair< std::string, int >("Feb",2)); fMonth.insert(std::pair< std::string, int >("feb",2)); fMonth.insert(std::pair< std::string, int >("February",2)); fMonth.insert(std::pair< std::string, int >("february",2)); fMonth.insert(std::pair< std::string, int >("Mar",3)); fMonth.insert(std::pair< std::string, int >("mar",3)); fMonth.insert(std::pair< std::string, int >("March",3)); fMonth.insert(std::pair< std::string, int >("march",3)); fMonth.insert(std::pair< std::string, int >("Apr",4)); fMonth.insert(std::pair< std::string, int >("apr",4)); fMonth.insert(std::pair< std::string, int >("April",4)); fMonth.insert(std::pair< std::string, int >("april",4)); fMonth.insert(std::pair< std::string, int >("May",5)); fMonth.insert(std::pair< std::string, int >("may",5)); fMonth.insert(std::pair< std::string, int >("Jun",6)); fMonth.insert(std::pair< std::string, int >("jun",6)); fMonth.insert(std::pair< std::string, int >("June",6)); fMonth.insert(std::pair< std::string, int >("june",6)); fMonth.insert(std::pair< std::string, int >("Jul",7)); fMonth.insert(std::pair< std::string, int >("jul",7)); fMonth.insert(std::pair< std::string, int >("July",7)); fMonth.insert(std::pair< std::string, int >("july",7)); fMonth.insert(std::pair< std::string, int >("Aug",8)); fMonth.insert(std::pair< std::string, int >("aug",8)); fMonth.insert(std::pair< std::string, int >("August",8)); fMonth.insert(std::pair< std::string, int >("august",8)); fMonth.insert(std::pair< std::string, int >("Sep",9)); fMonth.insert(std::pair< std::string, int >("sep",9)); fMonth.insert(std::pair< std::string, int >("September",9)); fMonth.insert(std::pair< std::string, int >("september",9)); fMonth.insert(std::pair< std::string, int >("Oct",10)); fMonth.insert(std::pair< std::string, int >("oct",10)); fMonth.insert(std::pair< std::string, int >("October",10)); fMonth.insert(std::pair< std::string, int >("october",10)); fMonth.insert(std::pair< std::string, int >("Nov",11)); fMonth.insert(std::pair< std::string, int >("nov",11)); fMonth.insert(std::pair< std::string, int >("November",11)); fMonth.insert(std::pair< std::string, int >("november",11)); fMonth.insert(std::pair< std::string, int >("Dec",12)); fMonth.insert(std::pair< std::string, int >("dec",12)); fMonth.insert(std::pair< std::string, int >("December",12)); fMonth.insert(std::pair< std::string, int >("december",12)); } int Sc46SourceGen::GetMonthInt(std::string month) { // Find the month in the map and return the integer value for the month. If the // month is not found, then return the integer value of the argument passed, // as it could be that an integer value was set for the month in the database // rather than a name string if(fMonth.empty()) BuildMonthMap(); // This should never happen... std::map< std::string, int >::iterator itMonth; itMonth = fMonth.find(month); if(itMonth == fMonth.end()) return to_int(month); return (*itMonth).second; } } // namespace RAT