A lot of the files are identical to old ones, but the main changes are: 1) EXFit2.C in sx3cal - Finds front/right gains for each strip using the known middle two pad edges, but gainmatches all backs 2) Define new 'fix' loci, arising from the step-ladder correction to A1C2 events. This is tested in scratch/sx3z_vs_pcz/testmodel.h, will be given a better name in the future. 3) Explore A1C2 and A1C3 loci in detail 4) environment variables to 'flip' and 'offset' wires during sort. All env vars are set in shell scripts that call them 5) environment variables that allow for timestamp bounds to be set and unset. Default limiting values are 0 and dbl_max so no harm done unless these specific env vars are set. 6) Some bookkeeping indicating 27Al instead of 26Al in all places.
523 lines
15 KiB
C++
523 lines
15 KiB
C++
/***********************************************************************
|
|
*
|
|
* This is Isotope.h, To extract the isotope mass from massXX.txt
|
|
*
|
|
*-------------------------------------------------------
|
|
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
|
|
* email: goluckyryan@gmail.com
|
|
* ********************************************************************/
|
|
|
|
|
|
#ifndef ISOTOPE_H
|
|
#define ISOTOPE_H
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "constant.h" // amu
|
|
#include <stdlib.h> //atoi
|
|
#include <algorithm>
|
|
using namespace std;
|
|
|
|
string massData="mass20.txt";
|
|
|
|
// about the mass**.txt
|
|
// Mass Excess = (ATOMIC MASS - A)*amu | e.g. n : (1.088664.91585E-6-1)*amu
|
|
// mass excess uncertaintly
|
|
// BEA = (Z*M(1H) + N*M(1n) - Me(A,Z))/A , Me is the mass with electrons
|
|
// BEA = (Z*mp + N*mn - M(A,Z))/A , M is the mass without electrons
|
|
|
|
class Isotope {
|
|
public:
|
|
int A, Z;
|
|
double Mass, MassError, BEA;
|
|
string Name, Symbol;
|
|
string dataSource;
|
|
|
|
Isotope(){ dataSource = massData; };
|
|
Isotope(int a, int z){ dataSource = massData; SetIso(a,z); };
|
|
Isotope(string name){ dataSource = massData; SetIsoByName(name); };
|
|
|
|
void SetIso(int a, int z);
|
|
void SetIsoByName(string name);
|
|
|
|
double CalSp(int Np, int Nn); // this for the Np-proton, Nn-neutron removal
|
|
double CalSp2(int a, int z); // this is for (a,z) nucleus removal
|
|
|
|
double CalBeta(double T){
|
|
// double Etot = Mass + T;
|
|
double gamma = 1 + T/Mass;
|
|
double beta = sqrt(1 - 1 / gamma / gamma ) ;
|
|
return beta;
|
|
}
|
|
|
|
void Print();
|
|
void ListShell();
|
|
|
|
private:
|
|
void FindMassByAZ(int a, int z); // give mass, massError, BEA, Name, Symbol;
|
|
void FindMassByName(string name); // give Z, mass, massError, BEA;
|
|
|
|
int TwoJ(int nShell);
|
|
string Orbital(int nShell);
|
|
int magic(int i){
|
|
switch (i){
|
|
case 0: return 2; break;
|
|
case 1: return 8; break;
|
|
case 2: return 20; break;
|
|
case 3: return 28; break;
|
|
case 4: return 40; break;
|
|
case 5: return 50; break;
|
|
case 6: return 82; break;
|
|
case 7: return 128; break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int magicShellID(int i){
|
|
switch (i){
|
|
case 0: return 0; break;
|
|
case 1: return 2; break;
|
|
case 2: return 5; break;
|
|
case 3: return 6; break;
|
|
case 4: return 9; break;
|
|
case 5: return 10; break;
|
|
case 6: return 15; break;
|
|
case 7: return 21; break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int fileStartLine;
|
|
int fileEndLine;
|
|
int lineMass050_099;
|
|
int lineMass100_149;
|
|
int lineMass150_199;
|
|
int lineMass200;
|
|
|
|
|
|
void setFileLines(){
|
|
fileStartLine = 37;
|
|
fileEndLine = 3594;
|
|
|
|
lineMass050_099 = 466;
|
|
lineMass100_149 = 1160;
|
|
lineMass150_199 = 1994;
|
|
lineMass200 = 2774;
|
|
}
|
|
|
|
char * heliosPath;
|
|
bool isFindOnce;
|
|
|
|
|
|
};
|
|
|
|
inline void Isotope::SetIso(int a, int z){
|
|
this->A = a;
|
|
this->Z = z;
|
|
FindMassByAZ(a,z);
|
|
}
|
|
|
|
inline void Isotope::SetIsoByName(string name){
|
|
FindMassByName(name);
|
|
}
|
|
|
|
inline void Isotope::FindMassByAZ(int A, int Z){
|
|
string line;
|
|
int lineNum=0;
|
|
int list_A, list_Z;
|
|
|
|
ifstream myfile;
|
|
int flag=0;
|
|
|
|
setFileLines();
|
|
|
|
int numLineStart = fileStartLine;
|
|
int numLineEnd = fileEndLine;
|
|
|
|
if ( A >= 50 && A < 100) numLineStart = lineMass050_099;
|
|
if ( A >=100 && A < 150) numLineStart = lineMass100_149;
|
|
if ( A >=150 && A < 200) numLineStart = lineMass150_199;
|
|
if ( A >=200 ) numLineStart = lineMass200;
|
|
|
|
myfile.open(dataSource.c_str());
|
|
|
|
if (myfile.is_open()) {
|
|
while (/*! myfile.eof() &&*/ flag == 0 && lineNum <numLineEnd){
|
|
lineNum ++ ;
|
|
//printf("%3d ",lineNum);
|
|
getline (myfile,line);
|
|
|
|
if (lineNum >= numLineStart ){
|
|
list_Z = atoi((line.substr(10,5)).c_str());
|
|
list_A = atoi((line.substr(15,5)).c_str());
|
|
|
|
if ( A == list_A && Z == list_Z) {
|
|
this->BEA = atof((line.substr(54,11)).c_str());
|
|
this->Mass = list_Z*mp + (list_A-list_Z)*mn - this->BEA/1000*list_A;
|
|
this->MassError = atof((line.substr(65,7)).c_str());
|
|
string str = line.substr(20,2);
|
|
str.erase(remove(str.begin(), str.end(), ' '), str.end());
|
|
this->Symbol = str;
|
|
|
|
ostringstream ss;
|
|
ss << A << this->Symbol;
|
|
this->Name = ss.str();
|
|
flag = 1;
|
|
}else if ( list_A > A) {
|
|
this->BEA = -404;
|
|
this->Mass = -404;
|
|
this->MassError = -404;
|
|
this->Symbol = "non";
|
|
this->Name = "non";
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if( this->Name == "1H" ) this->Name = "p";
|
|
if( this->Name == "2H" ) this->Name = "d";
|
|
if( this->Name == "3H" ) this->Name = "t";
|
|
if( this->Name == "4He" ) this->Name = "a";
|
|
|
|
myfile.close();
|
|
}else {
|
|
printf("Unable to open %s\n", dataSource.c_str());
|
|
}
|
|
}
|
|
|
|
inline void Isotope::FindMassByName(string name){
|
|
|
|
// done seperate the Mass number and the name
|
|
if( name == "n" ) {
|
|
this->Name = "1n";
|
|
this->BEA = 0;
|
|
this->Mass = mn;
|
|
this->MassError = 0;
|
|
this->Name = "n";
|
|
this->A = 1;
|
|
this->Z = 0;
|
|
return;
|
|
}
|
|
if( name == "p" ) name = "1H";
|
|
if( name == "d" ) name = "2H";
|
|
if( name == "t" ) name = "3H";
|
|
if( name == "a" ) name = "4He";
|
|
|
|
string temp = name;
|
|
int lastDigit = 0;
|
|
|
|
for(int i=0; temp[i]; i++){
|
|
if(temp[i] == '0') lastDigit = i;
|
|
if(temp[i] == '1') lastDigit = i;
|
|
if(temp[i] == '2') lastDigit = i;
|
|
if(temp[i] == '3') lastDigit = i;
|
|
if(temp[i] == '4') lastDigit = i;
|
|
if(temp[i] == '5') lastDigit = i;
|
|
if(temp[i] == '6') lastDigit = i;
|
|
if(temp[i] == '7') lastDigit = i;
|
|
if(temp[i] == '8') lastDigit = i;
|
|
if(temp[i] == '9') lastDigit = i;
|
|
}
|
|
|
|
this->Symbol = temp.erase(0, lastDigit +1);
|
|
//check is Symbol is 2 charaters, if not, add " " at the end
|
|
if( this->Symbol.length() == 1 ){
|
|
this->Symbol = this->Symbol + " ";
|
|
}
|
|
|
|
|
|
temp = name;
|
|
int len = temp.length();
|
|
temp = temp.erase(lastDigit+1, len);
|
|
|
|
this->A = atoi(temp.c_str());
|
|
//printf(" Symbol = |%s| , Mass = %d\n", this->Symbol.c_str(), this->A);
|
|
|
|
// find the nucleus in the data
|
|
string line;
|
|
int lineNum=0;
|
|
int list_A;
|
|
string list_symbol;
|
|
|
|
ifstream myfile;
|
|
int flag=0;
|
|
|
|
setFileLines();
|
|
|
|
int numLineStart = fileStartLine;
|
|
int numLineEnd = fileEndLine;
|
|
|
|
if ( A >= 50 && A < 100) numLineStart = lineMass050_099;
|
|
if ( A >=100 && A < 150) numLineStart = lineMass100_149;
|
|
if ( A >=150 && A < 200) numLineStart = lineMass150_199;
|
|
if ( A >=200 ) numLineStart = lineMass200;
|
|
|
|
myfile.open(dataSource.c_str());
|
|
|
|
if (myfile.is_open()) {
|
|
while (/*! myfile.eof() &&*/ flag == 0 && lineNum <numLineEnd){
|
|
lineNum ++ ;
|
|
//printf("%3d ",lineNum);
|
|
getline (myfile,line);
|
|
|
|
if (lineNum >= numLineStart ){
|
|
list_symbol = line.substr(20,2);
|
|
list_A = atoi((line.substr(15,5)).c_str());
|
|
|
|
//printf(" A = %d, Sym = |%s| \n", list_A, list_symbol.c_str());
|
|
|
|
if ( this->A == list_A && this->Symbol == list_symbol) {
|
|
this->Z = atoi((line.substr(10,5)).c_str());
|
|
this->BEA = atof((line.substr(54,11)).c_str());
|
|
this->Mass = this->Z*mp + (list_A-this->Z)*mn - this->BEA/1000*list_A;
|
|
this->MassError = atof((line.substr(65,7)).c_str());
|
|
|
|
string str = line.substr(20,2);
|
|
str.erase(remove(str.begin(), str.end(), ' '), str.end());
|
|
this->Symbol = str;
|
|
|
|
ostringstream ss;
|
|
ss << this->A << this->Symbol;
|
|
this->Name = ss.str();
|
|
flag = 1;
|
|
}else if ( list_A > this->A) {
|
|
this->BEA = -404;
|
|
this->Mass = -404;
|
|
this->MassError = -404;
|
|
this->Symbol = "non";
|
|
this->Name = "non";
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
myfile.close();
|
|
}else {
|
|
printf("Unable to open %s\n", dataSource.c_str());
|
|
}
|
|
}
|
|
|
|
inline double Isotope::CalSp(int Np, int Nn){
|
|
Isotope nucleusD(A - Np - Nn, Z - Np);
|
|
|
|
if( nucleusD.Mass != -404){
|
|
return nucleusD.Mass + Nn*mn + Np*mp - this->Mass;
|
|
}else{
|
|
return -404;
|
|
}
|
|
}
|
|
|
|
inline double Isotope::CalSp2(int a, int z){
|
|
Isotope nucleusD(A - a , Z - z);
|
|
Isotope nucleusS(a,z);
|
|
|
|
if( nucleusD.Mass != -404 && nucleusS.Mass != -404){
|
|
return nucleusD.Mass + nucleusS.Mass - this->Mass;
|
|
}else{
|
|
return -404;
|
|
}
|
|
}
|
|
|
|
inline int Isotope::TwoJ(int nShell){
|
|
|
|
switch(nShell){
|
|
case 0: return 1; break; // 0s1/2
|
|
case 1: return 3; break; // 0p3/2
|
|
case 2: return 1; break; // 0p1/2 -- 8
|
|
case 3: return 5; break; // 0d5/2
|
|
case 4: return 1; break; // 1s1/2
|
|
case 5: return 3; break; // 0d3/2 -- 20
|
|
case 6: return 7; break; // 0f7/2 -- 28
|
|
case 7: return 3; break; // 1p3/2
|
|
case 8: return 1; break; // 1p1/2
|
|
case 9: return 5; break; // 0f5/2 -- 40
|
|
case 10: return 9; break; // 0g9/2 -- 50
|
|
case 11: return 7; break; // 0g7/2
|
|
case 12: return 5; break; // 1d5/2
|
|
case 13: return 11; break; // 0h11/2
|
|
case 14: return 3; break; // 1d3/2
|
|
case 15: return 1; break; // 2s1/2 -- 82
|
|
case 16: return 9; break; // 0h9/2
|
|
case 17: return 7; break; // 1f7/2
|
|
case 18: return 13; break; // 0i13/2
|
|
case 19: return 3; break; // 2p3/2
|
|
case 20: return 5; break; // 1f5/2
|
|
case 21: return 1; break; // 1p1/2 -- 126
|
|
case 22: return 9; break; // 1g9/2
|
|
case 23: return 11; break; // 0i11/2
|
|
case 24: return 15; break; // 0j15/2
|
|
case 25: return 5; break; // 2d5/2
|
|
case 26: return 1; break; // 3s1/2
|
|
case 27: return 3; break; // 2d3/2
|
|
case 28: return 7; break; // 1g7/2
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
inline string Isotope::Orbital(int nShell){
|
|
|
|
switch(nShell){
|
|
case 0: return "0s1 "; break; //
|
|
case 1: return "0p3 "; break; //
|
|
case 2: return "0p1 "; break; //-- 8
|
|
case 3: return "0d5 "; break; //
|
|
case 4: return "1s1 "; break; //
|
|
case 5: return "0d3 "; break; //-- 20
|
|
case 6: return "0f7 "; break; //-- 28
|
|
case 7: return "1p3 "; break; //
|
|
case 8: return "1p1 "; break; //
|
|
case 9: return "0f5 "; break; //-- 40
|
|
case 10: return "0g9 "; break; //-- 50
|
|
case 11: return "0g7 "; break; //
|
|
case 12: return "1d5 "; break; //
|
|
case 13: return "0h11"; break; //
|
|
case 14: return "1d3 "; break; //
|
|
case 15: return "2s1 "; break; //-- 82
|
|
case 16: return "0h9 "; break; //
|
|
case 17: return "1f7 "; break; //
|
|
case 18: return "0i13"; break; //
|
|
case 19: return "2p3 "; break; //
|
|
case 20: return "1f5 "; break; //
|
|
case 21: return "1p1 "; break; //-- 126
|
|
case 22: return "1g9 "; break; //
|
|
case 23: return "0i11"; break; //
|
|
case 24: return "0j15"; break; //
|
|
case 25: return "2d5 "; break; //
|
|
case 26: return "3s1 "; break; //
|
|
case 27: return "2d3 "; break; //
|
|
case 28: return "1g7 "; break; //
|
|
}
|
|
|
|
return "nan";
|
|
}
|
|
|
|
inline void Isotope::ListShell(){
|
|
|
|
if( Mass < 0 ) return;
|
|
|
|
int n = A-Z;
|
|
int p = Z;
|
|
|
|
int k = std::min(n,p);
|
|
int nMagic = 0;
|
|
for( int i = 0; i < 7; i++){
|
|
if( magic(i) < k && k <= magic(i+1) ){
|
|
nMagic = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int coreShell = magicShellID(nMagic-1);
|
|
int coreZ1 = magic(nMagic-1);
|
|
int coreZ2 = magic(nMagic);
|
|
|
|
Isotope core1( 2*coreZ1, coreZ1);
|
|
Isotope core2( 2*coreZ2, coreZ2);
|
|
|
|
printf("------------------ Core:%3s, inner Core:%3s \n", (core2.Name).c_str(), (core1.Name).c_str());
|
|
printf(" || ");
|
|
int t = std::max(n,p);
|
|
int nShell = 0;
|
|
do{
|
|
int occ = TwoJ(nShell)+1;
|
|
if( nShell > coreShell) {
|
|
printf("%4s", Orbital(nShell).c_str());
|
|
if( nShell == 0 || nShell == 2 || nShell == 5 || nShell ==6 || nShell == 9 || nShell == 10 || nShell == 15 || nShell == 21){
|
|
printf("|");
|
|
}else{
|
|
printf(",");
|
|
}
|
|
}
|
|
t = t - occ;
|
|
nShell++;
|
|
}while( t > 0 && nShell < 29);
|
|
for( int i = 1; i <= 6; i++){
|
|
if (nShell < 28) {
|
|
printf("%4s,", Orbital(nShell).c_str());
|
|
}else if( nShell == 28 ) {
|
|
printf("%4s", Orbital(nShell).c_str());
|
|
}
|
|
nShell ++;
|
|
}
|
|
if (nShell < 29) printf("%4s", Orbital(nShell).c_str());
|
|
printf("\n");
|
|
|
|
|
|
printf(" Z = %3d || ", p);
|
|
nShell = 0;
|
|
do{
|
|
int occ = TwoJ(nShell)+1;
|
|
if( nShell > coreShell ){
|
|
if( p > occ ) {
|
|
printf("%-4d", occ);
|
|
if( nShell == 0 || nShell == 2 || nShell == 5 || nShell ==6 || nShell == 9 || nShell == 10 || nShell == 15 || nShell == 21){
|
|
printf("|");
|
|
}else{
|
|
printf(",");
|
|
}
|
|
}else{
|
|
printf("%-4d", p);
|
|
}
|
|
}
|
|
p = p - occ;
|
|
nShell++;
|
|
}while( p > 0 && nShell < 29);
|
|
printf("\n");
|
|
|
|
printf(" N = %3d || ", n);
|
|
nShell = 0;
|
|
do{
|
|
int occ = TwoJ(nShell)+1;
|
|
if ( nShell > coreShell ){
|
|
if( n > occ ) {
|
|
printf("%-4d", occ);
|
|
if( nShell == 0 || nShell == 2 || nShell == 5 || nShell ==6 || nShell == 9 || nShell == 10 || nShell == 15 || nShell == 21){
|
|
printf("|");
|
|
}else{
|
|
printf(",");
|
|
}
|
|
}else{
|
|
printf("%-4d", n);
|
|
}
|
|
}
|
|
n = n - occ;
|
|
nShell++;
|
|
}while( n > 0 && nShell < 29);
|
|
printf("\n");
|
|
|
|
printf("------------------ \n");
|
|
}
|
|
|
|
|
|
inline void Isotope::Print(){
|
|
|
|
if (Mass > 0){
|
|
|
|
dataSource = massData;
|
|
|
|
printf(" using mass data : %s \n", dataSource.c_str());
|
|
printf(" mass of \e[47m\e[31m%s\e[m nucleus (Z,A)=(%3d,%3d) is \e[47m\e[31m%12.5f\e[m MeV, BE/A=%7.5f MeV\n", Name.c_str(), Z, A, Mass, BEA/1000.);
|
|
printf(" total BE : %12.5f MeV\n",BEA*A/1000.);
|
|
printf(" mass in amu : %12.5f u\n",Mass/amu);
|
|
printf(" mass excess : %12.5f MeV\n", Mass + Z*0.510998950 - A*amu);
|
|
printf("-------------- Seperation energy \n");
|
|
printf(" S1p: %8.4f| S1n: %8.4f| S(2H ): %8.4f| S1p1n : %8.4f\n", CalSp(1, 0), CalSp(0, 1), CalSp2(2, 1), CalSp(1, 1));
|
|
printf(" S2p: %8.4f| S2n: %8.4f| S(3He): %8.4f| S(3H) : %8.4f\n", CalSp(2, 0), CalSp(0, 2), CalSp2(3, 2), CalSp2(3, 1));
|
|
printf(" S3p: %8.4f| S3n: %8.4f| S(4He): %8.4f|\n", CalSp(3, 0), CalSp(0, 3), CalSp2(4, 2));
|
|
printf(" S4p: %8.4f| S4n: %8.4f| \n", CalSp(4, 0), CalSp(0, 4));
|
|
|
|
}else{
|
|
printf("Error %6.0f, no nucleus with (Z,A) = (%3d,%3d). \n", Mass, Z, A);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
#endif
|