MUSASHI C source: xtcorrelation.c
0001: /*============================================================================*/
0002: /* 変更履歴 */
0003: /*----------------------------------------------------------------------------*/
0004: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0005: /*============================================================================*/
0006:
0007: #include <musashi.h>
0008: #include <math.h>
0009: #include <stdlib.h>
0010:
0011: #include <xtcorrelationHelp.h>
0012: struct mssComHelp comHelp={
0013: "xtcorrelation",/* コマンド名 */
0014: "1.0", /* バージョン */
0015: HELPT, /* コマンドタイトル */
0016: HELPS, /* 要約 */
0017: HELPE, /* 利用例 */
0018: HELPR, /* 参照コマンド */
0019: HELPA, /* 作者情報 */
0020: HELPB, /* バグレポート情報 */
0021: HELPH /* ホームページ */
0022: };
0023:
0024: extern struct mssGlobalVariables mssGV;
0025:
0026: int main(int argc, char *argv[]){
0027: /*============================================================================*/
0028: /* オプション宣言&定義 */
0029: /*============================================================================*/
0030: /*----------------------------------------------------------------------------*/
0031: /* キー項目 */
0032: /*----------------------------------------------------------------------------*/
0033: MssOptKEY optKEY={
0034: OKEY, /* オプションタイプ */
0035: "k", /* キーワード(複数文字は不可) */
0036: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0037: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0038: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0039: 2, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0040: /* 1:全ての行を異るキー値として扱う */
0041: /* 2:全ての行を同じキー値として扱う) */
0042: KEYT, /* このオプションのタイトル(Helpで表示) */
0043: KEYC /* このオプションのコメント(Helpで表示) */
0044: };
0045:
0046: /*----------------------------------------------------------------------------*/
0047: /* 対象項目 */
0048: /*----------------------------------------------------------------------------*/
0049: MssOptFLD optFLD={
0050: OFLD, /* オプションタイプ */
0051: "f", /* キーワード(複数文字は不可) */
0052: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0053: 2, /* 指定可能な最大項目数 */
0054: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0055: 0, /* 正規表現を許可するかどうか(0:不可,1:可) */
0056: 0, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0057: NULL, /* 項目オプション(%以下)で指定可能な文字 */
0058: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0059: FLDT, /* このオプションのタイトル(Helpで表示) */
0060: FLDC, /* このオプションのコメント(Helpで表示) */
0061: FLDF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0062: };
0063:
0064: /*----------------------------------------------------------------------------*/
0065: /* 新項目名 */
0066: /*----------------------------------------------------------------------------*/
0067: MssOptSLS optFNM={
0068: OSLS, /* オプションタイプ */
0069: "a", /* キーワード(複数文字は不可) */
0070: 2, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0071: NULL, /* デフォルト(文字列) */
0072: 1, /* カンマで区切られる要素数の最大値 */
0073: 1, /* 各要素の文字列長の最小値 */
0074: MssFieldNameMaxLen,/* 各要素の文字列長の最大値 */
0075: 0, /* 1:要素にコロンを指定できる,0:不可 ex) aaaa:xxxxx */
0076: FNMT, /* このオプションのタイトル(Helpで表示) */
0077: FNMC /* このオプションのコメント(Helpで表示) */
0078: };
0079:
0080: /*----------------------------------------------------------------------------*/
0081: /* シーケンシャル処理 */
0082: /*----------------------------------------------------------------------------*/
0083: MssOptFLG optSEQ={
0084: OFLG, /* オプションタイプ */
0085: "q", /* キーワード(複数文字は不可) */
0086: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0087: SEQT, /* このオプションのタイトル(Helpで表示) */
0088: SEQC /* このオプションのコメント(Helpで表示) */
0089: };
0090:
0091: /*----------------------------------------------------------------------------*/
0092: /* 入力ファイル */
0093: /*----------------------------------------------------------------------------*/
0094: MssOptINF optINF={
0095: OINF, /* オプションタイプ */
0096: "i", /* キーワード(複数文字は不可) */
0097: 0, /* 0:オプション, 1:必須 */
0098: 1, /* 指定可能の最大ファイル数 */
0099: 0, /*1:file not foundのエラーで終了しない 0:する */
0100: INFT, /* このオプションのタイトル(Helpで表示) */
0101: INFC /* このオプションのコメント(Helpで表示) */
0102: };
0103:
0104: /*----------------------------------------------------------------------------*/
0105: /* 出力ファイル */
0106: /*----------------------------------------------------------------------------*/
0107: MssOptOTF optOTF={
0108: OOTF, /* オプションタイプ */
0109: "o", /* キーワード(複数文字は不可) */
0110: 0, /* 0:オプション, 1:必須 */
0111: OTFT, /* このオプションのタイトル(Helpで表示) */
0112: OTFC /* このオプションのコメント(Helpで表示) */
0113: };
0114:
0115: /*----------------------------------------------------------------------------*/
0116: /* 圧縮出力 */
0117: /*----------------------------------------------------------------------------*/
0118: MssOptFLG optZIP={
0119: OFLG, /* オプションタイプ */
0120: "z", /* キーワード(複数文字は不可) */
0121: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0122: ZIPT, /* このオプションのタイトル(Helpで表示) */
0123: ZIPC /* このオプションのコメント(Helpで表示) */
0124: };
0125:
0126: /*----------------------------------------------------------------------------*/
0127: /* plain text */
0128: /*----------------------------------------------------------------------------*/
0129: MssOptFLG optTXT={
0130: OFLG, /* オプションタイプ */
0131: "t", /* キーワード(複数文字は不可) */
0132: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0133: TXTT, /* このオプションのタイトル(Helpで表示) */
0134: TXTC /* このオプションのコメント(Helpで表示) */
0135: };
0136:
0137: /*----------------------------------------------------------------------------*/
0138: /* ワークファイル用ディレクトリ名 */
0139: /*----------------------------------------------------------------------------*/
0140: MssOptSTR optTMP={
0141: OSTR, /* オプションタイプ */
0142: "T", /* キーワード(複数文字は不可) */
0143: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0144: MssTempDir, /* デフォルト */
0145: 1, /* 文字列の最小長 */
0146: MssFileNameMaxLen, /* 文字列の最大長 */
0147: TMPT, /* このオプションのタイトル(Helpで表示) */
0148: TMPC /* このオプションのコメント(Helpで表示) */
0149: };
0150:
0151: /*----------------------------------------------------------------------------*/
0152: /* オプションをまとめる */
0153: /*----------------------------------------------------------------------------*/
0154: void *opt[]={&optKEY,&optFLD,&optFNM,&optSEQ,
0155: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0156:
0157: /*============================================================================*/
0158: /* 変数宣言&定義 */
0159: /*============================================================================*/
0160: struct mssHeader *hdi; /*入力ファイル用<head>タグ格納構造体*/
0161: struct mssHeader *hdo; /*出力ファイル用<head>タグ格納構造体*/
0162: struct mssFPR *fpr; /*入力ファイル構造体 */
0163: struct mssFPW *fpw; /*出力ファイル構造体 */
0164: struct mssFldRecDbl *frd; /*項目-二行バッファ構造体 */
0165: struct mssFields *sf; /*ソート項目構造体 */
0166: int sorted; /*ソート済チェック用 */
0167:
0168: double sx,sy,sxx,syy,sxy,dx,dy;
0169: int keyCnt=0;
0170: char *str1;
0171: char *str2;
0172:
0173: /*----------------------------------------------------------------------------*/
0174: /* 前処理 */
0175: /*----------------------------------------------------------------------------*/
0176: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0177: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0178: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0179: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0180: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0181: mssSetOptKey(&optKEY, hdi); /* -k 項目をヘッダー項目に関連づける */
0182: mssSetOptFld(&optFLD, hdi); /* -f 項目をヘッダー項目に関連づける */
0183:
0184: /*ソート項目の作成*/
0185: sf=mssInitFields();
0186: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0187: mssSetFieldsSortPriority(sf); /* ソート優先順位番号を登録順にふる */
0188: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0189:
0190: /*mssShowFields(sf);*/
0191: /*mssShowOption(opt);*/
0192: /*mssShowHeader(hdi);*/
0193:
0194: if(optFLD.flds->cnt!=2){
0195: mssShowErrMsg("-f must have 2 fields");
0196: mssEnd(mssErrorNoDefault);
0197: }
0198:
0199: /*----------------------------------------------------------------------------*/
0200: /*出力ヘッダーの作成と出力 */
0201: /*----------------------------------------------------------------------------*/
0202: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0203: hdo=mssInitCpyHeader(hdi);
0204:
0205: /*入力ヘッダの全項目を追加*/
0206: mssAddFieldsByFields(hdo->flds,hdi->flds);
0207:
0208: /*新項目名を追加する*/
0209: mssAddFieldsByStrList(hdo->flds,optFNM.strList,optFNM.cnt);
0210:
0211: /*ソートする必要があるならばsfのソート情報を反映*/
0212: if(!optSEQ.set && !sorted){
0213: mssSetFieldsSort(hdo->flds,sf);
0214: }
0215:
0216: /*標準出力オープン+ヘッダーの出力*/
0217: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0218: mssWriteHeader(hdo, fpw);
0219:
0220: /*----------------------------------------------------------------------------*/
0221: /*メインルーチン */
0222: /*----------------------------------------------------------------------------*/
0223: /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/
0224: if( !optSEQ.set && !sorted){
0225: fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str);
0226: }
0227:
0228: /*FRD構造体の初期化*/
0229: frd=mssInitFRD(hdi->flds->cnt);
0230:
0231: sx=sy=sxx=syy=sxy=dx=dy=0;
0232: while( EOF!= mssReadFRD(fpr,frd) ){
0233: /*キーブレイク時の処理*/
0234: if(mssKeyBreak(frd, &optKEY)){
0235: /*一行書き出し*/
0236: mssWriteFld(frd->pnt[frd->old],frd->fldCnt," ",fpw);
0237: if(keyCnt != 1) {
0238: sxx = sqrt(sxx / (double)(keyCnt-1));
0239: syy = sqrt(syy / (double)(keyCnt-1));
0240: if(sxx != 0 && syy !=0) {
0241: sxy /= (double)(keyCnt-1) * sxx * syy;
0242: mssWriteDbl(sxy,fpw);
0243: } else {
0244: mssWriteNull(fpw);
0245: }
0246: }else {
0247: mssWriteNull(fpw);
0248: }
0249: mssWriteRet(fpw);
0250: mssGV.outCnt++;
0251: if(frd->eof) break;
0252:
0253: /*集計値の初期化*/
0254: sx = sy = sxx = syy = sxy = 0;
0255: keyCnt=0;
0256: }
0257:
0258: mssGV.inCnt++;
0259:
0260: /*通常行の処理*/
0261: str1=*(frd->pnt[frd->new]+MssFlds2num(optFLD.flds,0));
0262: str2=*(frd->pnt[frd->new]+MssFlds2num(optFLD.flds,1));
0263: if( !MssIsNull(str1) && !MssIsNull(str2) ){
0264: dx=atof(str1) - sx;
0265: dy=atof(str2) - sy;
0266: sx += dx / (double)(keyCnt+1);
0267: sy += dy / (double)(keyCnt+1);
0268: sxx += (double)keyCnt * dx * dx / (double)(keyCnt+1);
0269: syy += (double)keyCnt * dy * dy / (double)(keyCnt+1);
0270: sxy += (double)keyCnt * dx * dy / (double)(keyCnt+1);
0271: keyCnt++;
0272: }
0273: }
0274: mssFreeFRD(frd);
0275:
0276: /*----------------------------------------------------------------------------*/
0277: /*フッター出力&終了処理 */
0278: /*----------------------------------------------------------------------------*/
0279: /*printf("allocCnt=%d\n",getAllocCnt());*/
0280: mssWriteFooter(fpw); /* フッターの出力 */
0281: mssCloseFPR(fpr); /* 入力ファイルのクローズ */
0282: mssCloseFPW(fpw); /* 出力ファイルのクローズ */
0283: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0284: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0285: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0286: mssFreeOption(opt); /* オプション領域開放 */
0287: mssShowEndMsg(); /* 完了メッセージ */
0288: return(0); /* to avoid warning message */
0289: }